diff options
| author | Mike Rapoport <mike@compulab.co.il> | 2008-12-03 03:48:52 -0500 |
|---|---|---|
| committer | Richard Purdie <rpurdie@linux.intel.com> | 2009-01-08 15:11:07 -0500 |
| commit | f4f6bda00fc6bf995a35d8246db45aacaa9b3f09 (patch) | |
| tree | 6bcd025f254aad632f910f0e25531c693a27bc60 /drivers/video | |
| parent | c835ee7f4154992e6cf0674d7ee136f5d36247a4 (diff) | |
backlight: add support for Toppoly TDO35S series to tdo24m lcd driver
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Acked-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'drivers/video')
| -rw-r--r-- | drivers/video/backlight/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/video/backlight/tdo24m.c | 94 |
2 files changed, 88 insertions, 10 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 4a4dd9adc328..7ee2313ed6b8 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
| @@ -52,11 +52,11 @@ config LCD_ILI9320 | |||
| 52 | then say y to include a power driver for it. | 52 | then say y to include a power driver for it. |
| 53 | 53 | ||
| 54 | config LCD_TDO24M | 54 | config LCD_TDO24M |
| 55 | tristate "Toppoly TDO24M LCD Panels support" | 55 | tristate "Toppoly TDO24M and TDO35S LCD Panels support" |
| 56 | depends on LCD_CLASS_DEVICE && SPI_MASTER | 56 | depends on LCD_CLASS_DEVICE && SPI_MASTER |
| 57 | default n | 57 | default n |
| 58 | help | 58 | help |
| 59 | If you have a Toppoly TDO24M series LCD panel, say y here to | 59 | If you have a Toppoly TDO24M/TDO35S series LCD panel, say y here to |
| 60 | include the support for it. | 60 | include the support for it. |
| 61 | 61 | ||
| 62 | config LCD_VGG2432A4 | 62 | config LCD_VGG2432A4 |
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index 8427669162ea..1dae7f8f3c6b 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
| 16 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
| 17 | #include <linux/spi/tdo24m.h> | ||
| 17 | #include <linux/fb.h> | 18 | #include <linux/fb.h> |
| 18 | #include <linux/lcd.h> | 19 | #include <linux/lcd.h> |
| 19 | 20 | ||
| @@ -31,6 +32,9 @@ struct tdo24m { | |||
| 31 | struct spi_transfer xfer; | 32 | struct spi_transfer xfer; |
| 32 | uint8_t *buf; | 33 | uint8_t *buf; |
| 33 | 34 | ||
| 35 | int (*adj_mode)(struct tdo24m *lcd, int mode); | ||
| 36 | int color_invert; | ||
| 37 | |||
| 34 | int power; | 38 | int power; |
| 35 | int mode; | 39 | int mode; |
| 36 | }; | 40 | }; |
| @@ -66,7 +70,7 @@ static uint32_t lcd_panel_off[] = { | |||
| 66 | CMD_NULL, | 70 | CMD_NULL, |
| 67 | }; | 71 | }; |
| 68 | 72 | ||
| 69 | static uint32_t lcd_vga_pass_through[] = { | 73 | static uint32_t lcd_vga_pass_through_tdo24m[] = { |
| 70 | CMD1(0xB0, 0x16), | 74 | CMD1(0xB0, 0x16), |
| 71 | CMD1(0xBC, 0x80), | 75 | CMD1(0xBC, 0x80), |
| 72 | CMD1(0xE1, 0x00), | 76 | CMD1(0xE1, 0x00), |
| @@ -75,7 +79,7 @@ static uint32_t lcd_vga_pass_through[] = { | |||
| 75 | CMD_NULL, | 79 | CMD_NULL, |
| 76 | }; | 80 | }; |
| 77 | 81 | ||
| 78 | static uint32_t lcd_qvga_pass_through[] = { | 82 | static uint32_t lcd_qvga_pass_through_tdo24m[] = { |
| 79 | CMD1(0xB0, 0x16), | 83 | CMD1(0xB0, 0x16), |
| 80 | CMD1(0xBC, 0x81), | 84 | CMD1(0xBC, 0x81), |
| 81 | CMD1(0xE1, 0x00), | 85 | CMD1(0xE1, 0x00), |
| @@ -84,7 +88,7 @@ static uint32_t lcd_qvga_pass_through[] = { | |||
| 84 | CMD_NULL, | 88 | CMD_NULL, |
| 85 | }; | 89 | }; |
| 86 | 90 | ||
| 87 | static uint32_t lcd_vga_transfer[] = { | 91 | static uint32_t lcd_vga_transfer_tdo24m[] = { |
| 88 | CMD1(0xcf, 0x02), /* Blanking period control (1) */ | 92 | CMD1(0xcf, 0x02), /* Blanking period control (1) */ |
| 89 | CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */ | 93 | CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */ |
| 90 | CMD1(0xd1, 0x01), /* CKV timing control on/off */ | 94 | CMD1(0xd1, 0x01), /* CKV timing control on/off */ |
| @@ -110,6 +114,35 @@ static uint32_t lcd_qvga_transfer[] = { | |||
| 110 | CMD_NULL, | 114 | CMD_NULL, |
| 111 | }; | 115 | }; |
| 112 | 116 | ||
| 117 | static uint32_t lcd_vga_pass_through_tdo35s[] = { | ||
| 118 | CMD1(0xB0, 0x16), | ||
| 119 | CMD1(0xBC, 0x80), | ||
| 120 | CMD1(0xE1, 0x00), | ||
| 121 | CMD1(0x3B, 0x00), | ||
| 122 | CMD_NULL, | ||
| 123 | }; | ||
| 124 | |||
| 125 | static uint32_t lcd_qvga_pass_through_tdo35s[] = { | ||
| 126 | CMD1(0xB0, 0x16), | ||
| 127 | CMD1(0xBC, 0x81), | ||
| 128 | CMD1(0xE1, 0x00), | ||
| 129 | CMD1(0x3B, 0x22), | ||
| 130 | CMD_NULL, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static uint32_t lcd_vga_transfer_tdo35s[] = { | ||
| 134 | CMD1(0xcf, 0x02), /* Blanking period control (1) */ | ||
| 135 | CMD2(0xd0, 0x08, 0x04), /* Blanking period control (2) */ | ||
| 136 | CMD1(0xd1, 0x01), /* CKV timing control on/off */ | ||
| 137 | CMD2(0xd2, 0x00, 0x1e), /* CKV 1,2 timing control */ | ||
| 138 | CMD2(0xd3, 0x14, 0x28), /* OEV timing control */ | ||
| 139 | CMD2(0xd4, 0x28, 0x64), /* ASW timing control (1) */ | ||
| 140 | CMD1(0xd5, 0x28), /* ASW timing control (2) */ | ||
| 141 | CMD0(0x21), /* Invert for normally black display */ | ||
| 142 | CMD0(0x29), /* Display on */ | ||
| 143 | CMD_NULL, | ||
| 144 | }; | ||
| 145 | |||
| 113 | static uint32_t lcd_panel_config[] = { | 146 | static uint32_t lcd_panel_config[] = { |
| 114 | CMD2(0xb8, 0xff, 0xf9), /* Output control */ | 147 | CMD2(0xb8, 0xff, 0xf9), /* Output control */ |
| 115 | CMD0(0x11), /* sleep out */ | 148 | CMD0(0x11), /* sleep out */ |
| @@ -148,6 +181,8 @@ static int tdo24m_writes(struct tdo24m *lcd, uint32_t *array) | |||
| 148 | int nparams, err = 0; | 181 | int nparams, err = 0; |
| 149 | 182 | ||
| 150 | for (; *p != CMD_NULL; p++) { | 183 | for (; *p != CMD_NULL; p++) { |
| 184 | if (!lcd->color_invert && *p == CMD0(0x21)) | ||
| 185 | continue; | ||
| 151 | 186 | ||
| 152 | nparams = (*p >> 30) & 0x3; | 187 | nparams = (*p >> 30) & 0x3; |
| 153 | 188 | ||
| @@ -184,12 +219,33 @@ static int tdo24m_adj_mode(struct tdo24m *lcd, int mode) | |||
| 184 | { | 219 | { |
| 185 | switch (mode) { | 220 | switch (mode) { |
| 186 | case MODE_VGA: | 221 | case MODE_VGA: |
| 187 | tdo24m_writes(lcd, lcd_vga_pass_through); | 222 | tdo24m_writes(lcd, lcd_vga_pass_through_tdo24m); |
| 188 | tdo24m_writes(lcd, lcd_panel_config); | 223 | tdo24m_writes(lcd, lcd_panel_config); |
| 189 | tdo24m_writes(lcd, lcd_vga_transfer); | 224 | tdo24m_writes(lcd, lcd_vga_transfer_tdo24m); |
| 190 | break; | 225 | break; |
| 191 | case MODE_QVGA: | 226 | case MODE_QVGA: |
| 192 | tdo24m_writes(lcd, lcd_qvga_pass_through); | 227 | tdo24m_writes(lcd, lcd_qvga_pass_through_tdo24m); |
| 228 | tdo24m_writes(lcd, lcd_panel_config); | ||
| 229 | tdo24m_writes(lcd, lcd_qvga_transfer); | ||
| 230 | break; | ||
| 231 | default: | ||
| 232 | return -EINVAL; | ||
| 233 | } | ||
| 234 | |||
| 235 | lcd->mode = mode; | ||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | static int tdo35s_adj_mode(struct tdo24m *lcd, int mode) | ||
| 240 | { | ||
| 241 | switch (mode) { | ||
| 242 | case MODE_VGA: | ||
| 243 | tdo24m_writes(lcd, lcd_vga_pass_through_tdo35s); | ||
| 244 | tdo24m_writes(lcd, lcd_panel_config); | ||
| 245 | tdo24m_writes(lcd, lcd_vga_transfer_tdo35s); | ||
| 246 | break; | ||
| 247 | case MODE_QVGA: | ||
| 248 | tdo24m_writes(lcd, lcd_qvga_pass_through_tdo35s); | ||
| 193 | tdo24m_writes(lcd, lcd_panel_config); | 249 | tdo24m_writes(lcd, lcd_panel_config); |
| 194 | tdo24m_writes(lcd, lcd_qvga_transfer); | 250 | tdo24m_writes(lcd, lcd_qvga_transfer); |
| 195 | break; | 251 | break; |
| @@ -213,7 +269,7 @@ static int tdo24m_power_on(struct tdo24m *lcd) | |||
| 213 | if (err) | 269 | if (err) |
| 214 | goto out; | 270 | goto out; |
| 215 | 271 | ||
| 216 | err = tdo24m_adj_mode(lcd, lcd->mode); | 272 | err = lcd->adj_mode(lcd, lcd->mode); |
| 217 | out: | 273 | out: |
| 218 | return err; | 274 | return err; |
| 219 | } | 275 | } |
| @@ -262,7 +318,7 @@ static int tdo24m_set_mode(struct lcd_device *ld, struct fb_videomode *m) | |||
| 262 | if (lcd->mode == mode) | 318 | if (lcd->mode == mode) |
| 263 | return 0; | 319 | return 0; |
| 264 | 320 | ||
| 265 | return tdo24m_adj_mode(lcd, mode); | 321 | return lcd->adj_mode(lcd, mode); |
| 266 | } | 322 | } |
| 267 | 323 | ||
| 268 | static struct lcd_ops tdo24m_ops = { | 324 | static struct lcd_ops tdo24m_ops = { |
| @@ -276,8 +332,16 @@ static int __devinit tdo24m_probe(struct spi_device *spi) | |||
| 276 | struct tdo24m *lcd; | 332 | struct tdo24m *lcd; |
| 277 | struct spi_message *m; | 333 | struct spi_message *m; |
| 278 | struct spi_transfer *x; | 334 | struct spi_transfer *x; |
| 335 | struct tdo24m_platform_data *pdata; | ||
| 336 | enum tdo24m_model model; | ||
| 279 | int err; | 337 | int err; |
| 280 | 338 | ||
| 339 | pdata = spi->dev.platform_data; | ||
| 340 | if (pdata) | ||
| 341 | model = pdata->model; | ||
| 342 | else | ||
| 343 | model = TDO24M; | ||
| 344 | |||
| 281 | spi->bits_per_word = 8; | 345 | spi->bits_per_word = 8; |
| 282 | spi->mode = SPI_MODE_3; | 346 | spi->mode = SPI_MODE_3; |
| 283 | err = spi_setup(spi); | 347 | err = spi_setup(spi); |
| @@ -306,6 +370,20 @@ static int __devinit tdo24m_probe(struct spi_device *spi) | |||
| 306 | x->tx_buf = &lcd->buf[0]; | 370 | x->tx_buf = &lcd->buf[0]; |
| 307 | spi_message_add_tail(x, m); | 371 | spi_message_add_tail(x, m); |
| 308 | 372 | ||
| 373 | switch (model) { | ||
| 374 | case TDO24M: | ||
| 375 | lcd->color_invert = 1; | ||
| 376 | lcd->adj_mode = tdo24m_adj_mode; | ||
| 377 | break; | ||
| 378 | case TDO35S: | ||
| 379 | lcd->adj_mode = tdo35s_adj_mode; | ||
| 380 | lcd->color_invert = 0; | ||
| 381 | break; | ||
| 382 | default: | ||
| 383 | dev_err(&spi->dev, "Unsupported model"); | ||
| 384 | goto out_free; | ||
| 385 | } | ||
| 386 | |||
| 309 | lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev, | 387 | lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev, |
| 310 | lcd, &tdo24m_ops); | 388 | lcd, &tdo24m_ops); |
| 311 | if (IS_ERR(lcd->lcd_dev)) { | 389 | if (IS_ERR(lcd->lcd_dev)) { |
