diff options
Diffstat (limited to 'drivers/video')
59 files changed, 1019 insertions, 8804 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4cf1e1dd5621..84b685f7ab6e 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -2100,13 +2100,6 @@ config GPM1040A0_320X240 | |||
2100 | bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" | 2100 | bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" |
2101 | depends on FB_NUC900 | 2101 | depends on FB_NUC900 |
2102 | 2102 | ||
2103 | config FB_NUC900_DEBUG | ||
2104 | bool "NUC900 lcd debug messages" | ||
2105 | depends on FB_NUC900 | ||
2106 | help | ||
2107 | Turn on debugging messages. Note that you can set/unset at run time | ||
2108 | through sysfs | ||
2109 | |||
2110 | config FB_SM501 | 2103 | config FB_SM501 |
2111 | tristate "Silicon Motion SM501 framebuffer support" | 2104 | tristate "Silicon Motion SM501 framebuffer support" |
2112 | depends on FB && MFD_SM501 | 2105 | depends on FB && MFD_SM501 |
@@ -2228,15 +2221,17 @@ config FB_SH7760 | |||
2228 | panels <= 320 pixel horizontal resolution. | 2221 | panels <= 320 pixel horizontal resolution. |
2229 | 2222 | ||
2230 | config FB_DA8XX | 2223 | config FB_DA8XX |
2231 | tristate "DA8xx/OMAP-L1xx Framebuffer support" | 2224 | tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support" |
2232 | depends on FB && ARCH_DAVINCI_DA8XX | 2225 | depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX) |
2233 | select FB_CFB_FILLRECT | 2226 | select FB_CFB_FILLRECT |
2234 | select FB_CFB_COPYAREA | 2227 | select FB_CFB_COPYAREA |
2235 | select FB_CFB_IMAGEBLIT | 2228 | select FB_CFB_IMAGEBLIT |
2236 | select FB_CFB_REV_PIXELS_IN_BYTE | 2229 | select FB_CFB_REV_PIXELS_IN_BYTE |
2230 | select FB_MODE_HELPERS | ||
2231 | select VIDEOMODE_HELPERS | ||
2237 | ---help--- | 2232 | ---help--- |
2238 | This is the frame buffer device driver for the TI LCD controller | 2233 | This is the frame buffer device driver for the TI LCD controller |
2239 | found on DA8xx/OMAP-L1xx SoCs. | 2234 | found on DA8xx/OMAP-L1xx/AM335x SoCs. |
2240 | If unsure, say N. | 2235 | If unsure, say N. |
2241 | 2236 | ||
2242 | config FB_VIRTUAL | 2237 | config FB_VIRTUAL |
@@ -2457,7 +2452,7 @@ config FB_HYPERV | |||
2457 | 2452 | ||
2458 | config FB_SIMPLE | 2453 | config FB_SIMPLE |
2459 | bool "Simple framebuffer support" | 2454 | bool "Simple framebuffer support" |
2460 | depends on (FB = y) && OF | 2455 | depends on (FB = y) |
2461 | select FB_CFB_FILLRECT | 2456 | select FB_CFB_FILLRECT |
2462 | select FB_CFB_COPYAREA | 2457 | select FB_CFB_COPYAREA |
2463 | select FB_CFB_IMAGEBLIT | 2458 | select FB_CFB_IMAGEBLIT |
@@ -2469,8 +2464,7 @@ config FB_SIMPLE | |||
2469 | pre-allocated frame buffer surface. | 2464 | pre-allocated frame buffer surface. |
2470 | 2465 | ||
2471 | Configuration re: surface address, size, and format must be provided | 2466 | Configuration re: surface address, size, and format must be provided |
2472 | through device tree, or potentially plain old platform data in the | 2467 | through device tree, or plain old platform data. |
2473 | future. | ||
2474 | 2468 | ||
2475 | source "drivers/video/omap/Kconfig" | 2469 | source "drivers/video/omap/Kconfig" |
2476 | source "drivers/video/omap2/Kconfig" | 2470 | source "drivers/video/omap2/Kconfig" |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index effdb373b8db..088511a58a26 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -902,14 +902,14 @@ static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo) | |||
902 | 902 | ||
903 | static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) | 903 | static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) |
904 | { | 904 | { |
905 | clk_enable(sinfo->bus_clk); | 905 | clk_prepare_enable(sinfo->bus_clk); |
906 | clk_enable(sinfo->lcdc_clk); | 906 | clk_prepare_enable(sinfo->lcdc_clk); |
907 | } | 907 | } |
908 | 908 | ||
909 | static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) | 909 | static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) |
910 | { | 910 | { |
911 | clk_disable(sinfo->bus_clk); | 911 | clk_disable_unprepare(sinfo->bus_clk); |
912 | clk_disable(sinfo->lcdc_clk); | 912 | clk_disable_unprepare(sinfo->lcdc_clk); |
913 | } | 913 | } |
914 | 914 | ||
915 | 915 | ||
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index a89c15de9f45..9b0f12c5c284 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -435,8 +435,8 @@ static int correct_chipset(struct atyfb_par *par) | |||
435 | const char *name; | 435 | const char *name; |
436 | int i; | 436 | int i; |
437 | 437 | ||
438 | for (i = ARRAY_SIZE(aty_chips); i > 0; i--) | 438 | for (i = (int)ARRAY_SIZE(aty_chips) - 1; i >= 0; i--) |
439 | if (par->pci_id == aty_chips[i - 1].pci_id) | 439 | if (par->pci_id == aty_chips[i].pci_id) |
440 | break; | 440 | break; |
441 | 441 | ||
442 | if (i < 0) | 442 | if (i < 0) |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 3fccb6d3c8c3..94a403a9717a 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -103,16 +103,16 @@ static void backlight_generate_event(struct backlight_device *bd, | |||
103 | sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); | 103 | sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); |
104 | } | 104 | } |
105 | 105 | ||
106 | static ssize_t backlight_show_power(struct device *dev, | 106 | static ssize_t bl_power_show(struct device *dev, struct device_attribute *attr, |
107 | struct device_attribute *attr, char *buf) | 107 | char *buf) |
108 | { | 108 | { |
109 | struct backlight_device *bd = to_backlight_device(dev); | 109 | struct backlight_device *bd = to_backlight_device(dev); |
110 | 110 | ||
111 | return sprintf(buf, "%d\n", bd->props.power); | 111 | return sprintf(buf, "%d\n", bd->props.power); |
112 | } | 112 | } |
113 | 113 | ||
114 | static ssize_t backlight_store_power(struct device *dev, | 114 | static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr, |
115 | struct device_attribute *attr, const char *buf, size_t count) | 115 | const char *buf, size_t count) |
116 | { | 116 | { |
117 | int rc; | 117 | int rc; |
118 | struct backlight_device *bd = to_backlight_device(dev); | 118 | struct backlight_device *bd = to_backlight_device(dev); |
@@ -136,8 +136,9 @@ static ssize_t backlight_store_power(struct device *dev, | |||
136 | 136 | ||
137 | return rc; | 137 | return rc; |
138 | } | 138 | } |
139 | static DEVICE_ATTR_RW(bl_power); | ||
139 | 140 | ||
140 | static ssize_t backlight_show_brightness(struct device *dev, | 141 | static ssize_t brightness_show(struct device *dev, |
141 | struct device_attribute *attr, char *buf) | 142 | struct device_attribute *attr, char *buf) |
142 | { | 143 | { |
143 | struct backlight_device *bd = to_backlight_device(dev); | 144 | struct backlight_device *bd = to_backlight_device(dev); |
@@ -145,7 +146,7 @@ static ssize_t backlight_show_brightness(struct device *dev, | |||
145 | return sprintf(buf, "%d\n", bd->props.brightness); | 146 | return sprintf(buf, "%d\n", bd->props.brightness); |
146 | } | 147 | } |
147 | 148 | ||
148 | static ssize_t backlight_store_brightness(struct device *dev, | 149 | static ssize_t brightness_store(struct device *dev, |
149 | struct device_attribute *attr, const char *buf, size_t count) | 150 | struct device_attribute *attr, const char *buf, size_t count) |
150 | { | 151 | { |
151 | int rc; | 152 | int rc; |
@@ -175,24 +176,27 @@ static ssize_t backlight_store_brightness(struct device *dev, | |||
175 | 176 | ||
176 | return rc; | 177 | return rc; |
177 | } | 178 | } |
179 | static DEVICE_ATTR_RW(brightness); | ||
178 | 180 | ||
179 | static ssize_t backlight_show_type(struct device *dev, | 181 | static ssize_t type_show(struct device *dev, struct device_attribute *attr, |
180 | struct device_attribute *attr, char *buf) | 182 | char *buf) |
181 | { | 183 | { |
182 | struct backlight_device *bd = to_backlight_device(dev); | 184 | struct backlight_device *bd = to_backlight_device(dev); |
183 | 185 | ||
184 | return sprintf(buf, "%s\n", backlight_types[bd->props.type]); | 186 | return sprintf(buf, "%s\n", backlight_types[bd->props.type]); |
185 | } | 187 | } |
188 | static DEVICE_ATTR_RO(type); | ||
186 | 189 | ||
187 | static ssize_t backlight_show_max_brightness(struct device *dev, | 190 | static ssize_t max_brightness_show(struct device *dev, |
188 | struct device_attribute *attr, char *buf) | 191 | struct device_attribute *attr, char *buf) |
189 | { | 192 | { |
190 | struct backlight_device *bd = to_backlight_device(dev); | 193 | struct backlight_device *bd = to_backlight_device(dev); |
191 | 194 | ||
192 | return sprintf(buf, "%d\n", bd->props.max_brightness); | 195 | return sprintf(buf, "%d\n", bd->props.max_brightness); |
193 | } | 196 | } |
197 | static DEVICE_ATTR_RO(max_brightness); | ||
194 | 198 | ||
195 | static ssize_t backlight_show_actual_brightness(struct device *dev, | 199 | static ssize_t actual_brightness_show(struct device *dev, |
196 | struct device_attribute *attr, char *buf) | 200 | struct device_attribute *attr, char *buf) |
197 | { | 201 | { |
198 | int rc = -ENXIO; | 202 | int rc = -ENXIO; |
@@ -205,6 +209,7 @@ static ssize_t backlight_show_actual_brightness(struct device *dev, | |||
205 | 209 | ||
206 | return rc; | 210 | return rc; |
207 | } | 211 | } |
212 | static DEVICE_ATTR_RO(actual_brightness); | ||
208 | 213 | ||
209 | static struct class *backlight_class; | 214 | static struct class *backlight_class; |
210 | 215 | ||
@@ -247,16 +252,15 @@ static void bl_device_release(struct device *dev) | |||
247 | kfree(bd); | 252 | kfree(bd); |
248 | } | 253 | } |
249 | 254 | ||
250 | static struct device_attribute bl_device_attributes[] = { | 255 | static struct attribute *bl_device_attrs[] = { |
251 | __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), | 256 | &dev_attr_bl_power.attr, |
252 | __ATTR(brightness, 0644, backlight_show_brightness, | 257 | &dev_attr_brightness.attr, |
253 | backlight_store_brightness), | 258 | &dev_attr_actual_brightness.attr, |
254 | __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, | 259 | &dev_attr_max_brightness.attr, |
255 | NULL), | 260 | &dev_attr_type.attr, |
256 | __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), | 261 | NULL, |
257 | __ATTR(type, 0444, backlight_show_type, NULL), | ||
258 | __ATTR_NULL, | ||
259 | }; | 262 | }; |
263 | ATTRIBUTE_GROUPS(bl_device); | ||
260 | 264 | ||
261 | /** | 265 | /** |
262 | * backlight_force_update - tell the backlight subsystem that hardware state | 266 | * backlight_force_update - tell the backlight subsystem that hardware state |
@@ -493,7 +497,7 @@ static int __init backlight_class_init(void) | |||
493 | return PTR_ERR(backlight_class); | 497 | return PTR_ERR(backlight_class); |
494 | } | 498 | } |
495 | 499 | ||
496 | backlight_class->dev_attrs = bl_device_attributes; | 500 | backlight_class->dev_groups = bl_device_groups; |
497 | backlight_class->pm = &backlight_class_dev_pm_ops; | 501 | backlight_class->pm = &backlight_class_dev_pm_ops; |
498 | return 0; | 502 | return 0; |
499 | } | 503 | } |
diff --git a/drivers/video/backlight/hx8357.c b/drivers/video/backlight/hx8357.c index a0482b567bfe..c7af8c45ab8a 100644 --- a/drivers/video/backlight/hx8357.c +++ b/drivers/video/backlight/hx8357.c | |||
@@ -71,11 +71,24 @@ | |||
71 | #define HX8357_SET_POWER_NORMAL 0xd2 | 71 | #define HX8357_SET_POWER_NORMAL 0xd2 |
72 | #define HX8357_SET_PANEL_RELATED 0xe9 | 72 | #define HX8357_SET_PANEL_RELATED 0xe9 |
73 | 73 | ||
74 | #define HX8369_SET_DISPLAY_BRIGHTNESS 0x51 | ||
75 | #define HX8369_WRITE_CABC_DISPLAY_VALUE 0x53 | ||
76 | #define HX8369_WRITE_CABC_BRIGHT_CTRL 0x55 | ||
77 | #define HX8369_WRITE_CABC_MIN_BRIGHTNESS 0x5e | ||
78 | #define HX8369_SET_POWER 0xb1 | ||
79 | #define HX8369_SET_DISPLAY_MODE 0xb2 | ||
80 | #define HX8369_SET_DISPLAY_WAVEFORM_CYC 0xb4 | ||
81 | #define HX8369_SET_VCOM 0xb6 | ||
82 | #define HX8369_SET_EXTENSION_COMMAND 0xb9 | ||
83 | #define HX8369_SET_GIP 0xd5 | ||
84 | #define HX8369_SET_GAMMA_CURVE_RELATED 0xe0 | ||
85 | |||
74 | struct hx8357_data { | 86 | struct hx8357_data { |
75 | unsigned im_pins[HX8357_NUM_IM_PINS]; | 87 | unsigned im_pins[HX8357_NUM_IM_PINS]; |
76 | unsigned reset; | 88 | unsigned reset; |
77 | struct spi_device *spi; | 89 | struct spi_device *spi; |
78 | int state; | 90 | int state; |
91 | bool use_im_pins; | ||
79 | }; | 92 | }; |
80 | 93 | ||
81 | static u8 hx8357_seq_power[] = { | 94 | static u8 hx8357_seq_power[] = { |
@@ -143,6 +156,61 @@ static u8 hx8357_seq_display_mode[] = { | |||
143 | HX8357_SET_DISPLAY_MODE_RGB_INTERFACE, | 156 | HX8357_SET_DISPLAY_MODE_RGB_INTERFACE, |
144 | }; | 157 | }; |
145 | 158 | ||
159 | static u8 hx8369_seq_write_CABC_min_brightness[] = { | ||
160 | HX8369_WRITE_CABC_MIN_BRIGHTNESS, 0x00, | ||
161 | }; | ||
162 | |||
163 | static u8 hx8369_seq_write_CABC_control[] = { | ||
164 | HX8369_WRITE_CABC_DISPLAY_VALUE, 0x24, | ||
165 | }; | ||
166 | |||
167 | static u8 hx8369_seq_set_display_brightness[] = { | ||
168 | HX8369_SET_DISPLAY_BRIGHTNESS, 0xFF, | ||
169 | }; | ||
170 | |||
171 | static u8 hx8369_seq_write_CABC_control_setting[] = { | ||
172 | HX8369_WRITE_CABC_BRIGHT_CTRL, 0x02, | ||
173 | }; | ||
174 | |||
175 | static u8 hx8369_seq_extension_command[] = { | ||
176 | HX8369_SET_EXTENSION_COMMAND, 0xff, 0x83, 0x69, | ||
177 | }; | ||
178 | |||
179 | static u8 hx8369_seq_display_related[] = { | ||
180 | HX8369_SET_DISPLAY_MODE, 0x00, 0x2b, 0x03, 0x03, 0x70, 0x00, | ||
181 | 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x01, | ||
182 | }; | ||
183 | |||
184 | static u8 hx8369_seq_panel_waveform_cycle[] = { | ||
185 | HX8369_SET_DISPLAY_WAVEFORM_CYC, 0x0a, 0x1d, 0x80, 0x06, 0x02, | ||
186 | }; | ||
187 | |||
188 | static u8 hx8369_seq_set_address_mode[] = { | ||
189 | HX8357_SET_ADDRESS_MODE, 0x00, | ||
190 | }; | ||
191 | |||
192 | static u8 hx8369_seq_vcom[] = { | ||
193 | HX8369_SET_VCOM, 0x3e, 0x3e, | ||
194 | }; | ||
195 | |||
196 | static u8 hx8369_seq_gip[] = { | ||
197 | HX8369_SET_GIP, 0x00, 0x01, 0x03, 0x25, 0x01, 0x02, 0x28, 0x70, | ||
198 | 0x11, 0x13, 0x00, 0x00, 0x40, 0x26, 0x51, 0x37, 0x00, 0x00, 0x71, | ||
199 | 0x35, 0x60, 0x24, 0x07, 0x0f, 0x04, 0x04, | ||
200 | }; | ||
201 | |||
202 | static u8 hx8369_seq_power[] = { | ||
203 | HX8369_SET_POWER, 0x01, 0x00, 0x34, 0x03, 0x00, 0x11, 0x11, 0x32, | ||
204 | 0x2f, 0x3f, 0x3f, 0x01, 0x3a, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, | ||
205 | }; | ||
206 | |||
207 | static u8 hx8369_seq_gamma_curve_related[] = { | ||
208 | HX8369_SET_GAMMA_CURVE_RELATED, 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d, | ||
209 | 0x2e, 0x4a, 0x08, 0x0e, 0x0f, 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e, | ||
210 | 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d, 0x2e, 0x4a, 0x08, 0x0e, 0x0f, | ||
211 | 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e, | ||
212 | }; | ||
213 | |||
146 | static int hx8357_spi_write_then_read(struct lcd_device *lcdev, | 214 | static int hx8357_spi_write_then_read(struct lcd_device *lcdev, |
147 | u8 *txbuf, u16 txlen, | 215 | u8 *txbuf, u16 txlen, |
148 | u8 *rxbuf, u16 rxlen) | 216 | u8 *rxbuf, u16 rxlen) |
@@ -219,6 +287,10 @@ static int hx8357_enter_standby(struct lcd_device *lcdev) | |||
219 | if (ret < 0) | 287 | if (ret < 0) |
220 | return ret; | 288 | return ret; |
221 | 289 | ||
290 | /* | ||
291 | * The controller needs 120ms when entering in sleep mode before we can | ||
292 | * send the command to go off sleep mode | ||
293 | */ | ||
222 | msleep(120); | 294 | msleep(120); |
223 | 295 | ||
224 | return 0; | 296 | return 0; |
@@ -232,6 +304,10 @@ static int hx8357_exit_standby(struct lcd_device *lcdev) | |||
232 | if (ret < 0) | 304 | if (ret < 0) |
233 | return ret; | 305 | return ret; |
234 | 306 | ||
307 | /* | ||
308 | * The controller needs 120ms when exiting from sleep mode before we | ||
309 | * can send the command to enter in sleep mode | ||
310 | */ | ||
235 | msleep(120); | 311 | msleep(120); |
236 | 312 | ||
237 | ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); | 313 | ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); |
@@ -241,18 +317,9 @@ static int hx8357_exit_standby(struct lcd_device *lcdev) | |||
241 | return 0; | 317 | return 0; |
242 | } | 318 | } |
243 | 319 | ||
244 | static int hx8357_lcd_init(struct lcd_device *lcdev) | 320 | static void hx8357_lcd_reset(struct lcd_device *lcdev) |
245 | { | 321 | { |
246 | struct hx8357_data *lcd = lcd_get_data(lcdev); | 322 | struct hx8357_data *lcd = lcd_get_data(lcdev); |
247 | int ret; | ||
248 | |||
249 | /* | ||
250 | * Set the interface selection pins to SPI mode, with three | ||
251 | * wires | ||
252 | */ | ||
253 | gpio_set_value_cansleep(lcd->im_pins[0], 1); | ||
254 | gpio_set_value_cansleep(lcd->im_pins[1], 0); | ||
255 | gpio_set_value_cansleep(lcd->im_pins[2], 1); | ||
256 | 323 | ||
257 | /* Reset the screen */ | 324 | /* Reset the screen */ |
258 | gpio_set_value(lcd->reset, 1); | 325 | gpio_set_value(lcd->reset, 1); |
@@ -260,7 +327,25 @@ static int hx8357_lcd_init(struct lcd_device *lcdev) | |||
260 | gpio_set_value(lcd->reset, 0); | 327 | gpio_set_value(lcd->reset, 0); |
261 | usleep_range(10000, 12000); | 328 | usleep_range(10000, 12000); |
262 | gpio_set_value(lcd->reset, 1); | 329 | gpio_set_value(lcd->reset, 1); |
330 | |||
331 | /* The controller needs 120ms to recover from reset */ | ||
263 | msleep(120); | 332 | msleep(120); |
333 | } | ||
334 | |||
335 | static int hx8357_lcd_init(struct lcd_device *lcdev) | ||
336 | { | ||
337 | struct hx8357_data *lcd = lcd_get_data(lcdev); | ||
338 | int ret; | ||
339 | |||
340 | /* | ||
341 | * Set the interface selection pins to SPI mode, with three | ||
342 | * wires | ||
343 | */ | ||
344 | if (lcd->use_im_pins) { | ||
345 | gpio_set_value_cansleep(lcd->im_pins[0], 1); | ||
346 | gpio_set_value_cansleep(lcd->im_pins[1], 0); | ||
347 | gpio_set_value_cansleep(lcd->im_pins[2], 1); | ||
348 | } | ||
264 | 349 | ||
265 | ret = hx8357_spi_write_array(lcdev, hx8357_seq_power, | 350 | ret = hx8357_spi_write_array(lcdev, hx8357_seq_power, |
266 | ARRAY_SIZE(hx8357_seq_power)); | 351 | ARRAY_SIZE(hx8357_seq_power)); |
@@ -341,6 +426,9 @@ static int hx8357_lcd_init(struct lcd_device *lcdev) | |||
341 | if (ret < 0) | 426 | if (ret < 0) |
342 | return ret; | 427 | return ret; |
343 | 428 | ||
429 | /* | ||
430 | * The controller needs 120ms to fully recover from exiting sleep mode | ||
431 | */ | ||
344 | msleep(120); | 432 | msleep(120); |
345 | 433 | ||
346 | ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); | 434 | ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); |
@@ -356,6 +444,96 @@ static int hx8357_lcd_init(struct lcd_device *lcdev) | |||
356 | return 0; | 444 | return 0; |
357 | } | 445 | } |
358 | 446 | ||
447 | static int hx8369_lcd_init(struct lcd_device *lcdev) | ||
448 | { | ||
449 | int ret; | ||
450 | |||
451 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_extension_command, | ||
452 | ARRAY_SIZE(hx8369_seq_extension_command)); | ||
453 | if (ret < 0) | ||
454 | return ret; | ||
455 | usleep_range(10000, 12000); | ||
456 | |||
457 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_display_related, | ||
458 | ARRAY_SIZE(hx8369_seq_display_related)); | ||
459 | if (ret < 0) | ||
460 | return ret; | ||
461 | |||
462 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_panel_waveform_cycle, | ||
463 | ARRAY_SIZE(hx8369_seq_panel_waveform_cycle)); | ||
464 | if (ret < 0) | ||
465 | return ret; | ||
466 | |||
467 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_address_mode, | ||
468 | ARRAY_SIZE(hx8369_seq_set_address_mode)); | ||
469 | if (ret < 0) | ||
470 | return ret; | ||
471 | |||
472 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_vcom, | ||
473 | ARRAY_SIZE(hx8369_seq_vcom)); | ||
474 | if (ret < 0) | ||
475 | return ret; | ||
476 | |||
477 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_gip, | ||
478 | ARRAY_SIZE(hx8369_seq_gip)); | ||
479 | if (ret < 0) | ||
480 | return ret; | ||
481 | |||
482 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_power, | ||
483 | ARRAY_SIZE(hx8369_seq_power)); | ||
484 | if (ret < 0) | ||
485 | return ret; | ||
486 | |||
487 | ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE); | ||
488 | if (ret < 0) | ||
489 | return ret; | ||
490 | |||
491 | /* | ||
492 | * The controller needs 120ms to fully recover from exiting sleep mode | ||
493 | */ | ||
494 | msleep(120); | ||
495 | |||
496 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_gamma_curve_related, | ||
497 | ARRAY_SIZE(hx8369_seq_gamma_curve_related)); | ||
498 | if (ret < 0) | ||
499 | return ret; | ||
500 | |||
501 | ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE); | ||
502 | if (ret < 0) | ||
503 | return ret; | ||
504 | usleep_range(1000, 1200); | ||
505 | |||
506 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_write_CABC_control, | ||
507 | ARRAY_SIZE(hx8369_seq_write_CABC_control)); | ||
508 | if (ret < 0) | ||
509 | return ret; | ||
510 | usleep_range(10000, 12000); | ||
511 | |||
512 | ret = hx8357_spi_write_array(lcdev, | ||
513 | hx8369_seq_write_CABC_control_setting, | ||
514 | ARRAY_SIZE(hx8369_seq_write_CABC_control_setting)); | ||
515 | if (ret < 0) | ||
516 | return ret; | ||
517 | |||
518 | ret = hx8357_spi_write_array(lcdev, | ||
519 | hx8369_seq_write_CABC_min_brightness, | ||
520 | ARRAY_SIZE(hx8369_seq_write_CABC_min_brightness)); | ||
521 | if (ret < 0) | ||
522 | return ret; | ||
523 | usleep_range(10000, 12000); | ||
524 | |||
525 | ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_display_brightness, | ||
526 | ARRAY_SIZE(hx8369_seq_set_display_brightness)); | ||
527 | if (ret < 0) | ||
528 | return ret; | ||
529 | |||
530 | ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); | ||
531 | if (ret < 0) | ||
532 | return ret; | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
359 | #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) | 537 | #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) |
360 | 538 | ||
361 | static int hx8357_set_power(struct lcd_device *lcdev, int power) | 539 | static int hx8357_set_power(struct lcd_device *lcdev, int power) |
@@ -388,10 +566,24 @@ static struct lcd_ops hx8357_ops = { | |||
388 | .get_power = hx8357_get_power, | 566 | .get_power = hx8357_get_power, |
389 | }; | 567 | }; |
390 | 568 | ||
569 | static const struct of_device_id hx8357_dt_ids[] = { | ||
570 | { | ||
571 | .compatible = "himax,hx8357", | ||
572 | .data = hx8357_lcd_init, | ||
573 | }, | ||
574 | { | ||
575 | .compatible = "himax,hx8369", | ||
576 | .data = hx8369_lcd_init, | ||
577 | }, | ||
578 | {}, | ||
579 | }; | ||
580 | MODULE_DEVICE_TABLE(of, hx8357_dt_ids); | ||
581 | |||
391 | static int hx8357_probe(struct spi_device *spi) | 582 | static int hx8357_probe(struct spi_device *spi) |
392 | { | 583 | { |
393 | struct lcd_device *lcdev; | 584 | struct lcd_device *lcdev; |
394 | struct hx8357_data *lcd; | 585 | struct hx8357_data *lcd; |
586 | const struct of_device_id *match; | ||
395 | int i, ret; | 587 | int i, ret; |
396 | 588 | ||
397 | lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); | 589 | lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); |
@@ -408,6 +600,10 @@ static int hx8357_probe(struct spi_device *spi) | |||
408 | 600 | ||
409 | lcd->spi = spi; | 601 | lcd->spi = spi; |
410 | 602 | ||
603 | match = of_match_device(hx8357_dt_ids, &spi->dev); | ||
604 | if (!match || !match->data) | ||
605 | return -EINVAL; | ||
606 | |||
411 | lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0); | 607 | lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0); |
412 | if (!gpio_is_valid(lcd->reset)) { | 608 | if (!gpio_is_valid(lcd->reset)) { |
413 | dev_err(&spi->dev, "Missing dt property: gpios-reset\n"); | 609 | dev_err(&spi->dev, "Missing dt property: gpios-reset\n"); |
@@ -424,25 +620,32 @@ static int hx8357_probe(struct spi_device *spi) | |||
424 | return -EINVAL; | 620 | return -EINVAL; |
425 | } | 621 | } |
426 | 622 | ||
427 | for (i = 0; i < HX8357_NUM_IM_PINS; i++) { | 623 | if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) { |
428 | lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, | 624 | lcd->use_im_pins = 1; |
429 | "im-gpios", i); | 625 | |
430 | if (lcd->im_pins[i] == -EPROBE_DEFER) { | 626 | for (i = 0; i < HX8357_NUM_IM_PINS; i++) { |
431 | dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n"); | 627 | lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, |
432 | return -EPROBE_DEFER; | 628 | "im-gpios", i); |
433 | } | 629 | if (lcd->im_pins[i] == -EPROBE_DEFER) { |
434 | if (!gpio_is_valid(lcd->im_pins[i])) { | 630 | dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n"); |
435 | dev_err(&spi->dev, "Missing dt property: im-gpios\n"); | 631 | return -EPROBE_DEFER; |
436 | return -EINVAL; | 632 | } |
437 | } | 633 | if (!gpio_is_valid(lcd->im_pins[i])) { |
438 | 634 | dev_err(&spi->dev, "Missing dt property: im-gpios\n"); | |
439 | ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i], | 635 | return -EINVAL; |
440 | GPIOF_OUT_INIT_LOW, "im_pins"); | 636 | } |
441 | if (ret) { | 637 | |
442 | dev_err(&spi->dev, "failed to request gpio %d: %d\n", | 638 | ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i], |
443 | lcd->im_pins[i], ret); | 639 | GPIOF_OUT_INIT_LOW, |
444 | return -EINVAL; | 640 | "im_pins"); |
641 | if (ret) { | ||
642 | dev_err(&spi->dev, "failed to request gpio %d: %d\n", | ||
643 | lcd->im_pins[i], ret); | ||
644 | return -EINVAL; | ||
645 | } | ||
445 | } | 646 | } |
647 | } else { | ||
648 | lcd->use_im_pins = 0; | ||
446 | } | 649 | } |
447 | 650 | ||
448 | lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops); | 651 | lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops); |
@@ -452,7 +655,9 @@ static int hx8357_probe(struct spi_device *spi) | |||
452 | } | 655 | } |
453 | spi_set_drvdata(spi, lcdev); | 656 | spi_set_drvdata(spi, lcdev); |
454 | 657 | ||
455 | ret = hx8357_lcd_init(lcdev); | 658 | hx8357_lcd_reset(lcdev); |
659 | |||
660 | ret = ((int (*)(struct lcd_device *))match->data)(lcdev); | ||
456 | if (ret) { | 661 | if (ret) { |
457 | dev_err(&spi->dev, "Couldn't initialize panel\n"); | 662 | dev_err(&spi->dev, "Couldn't initialize panel\n"); |
458 | goto init_error; | 663 | goto init_error; |
@@ -475,12 +680,6 @@ static int hx8357_remove(struct spi_device *spi) | |||
475 | return 0; | 680 | return 0; |
476 | } | 681 | } |
477 | 682 | ||
478 | static const struct of_device_id hx8357_dt_ids[] = { | ||
479 | { .compatible = "himax,hx8357" }, | ||
480 | {}, | ||
481 | }; | ||
482 | MODULE_DEVICE_TABLE(of, hx8357_dt_ids); | ||
483 | |||
484 | static struct spi_driver hx8357_driver = { | 683 | static struct spi_driver hx8357_driver = { |
485 | .probe = hx8357_probe, | 684 | .probe = hx8357_probe, |
486 | .remove = hx8357_remove, | 685 | .remove = hx8357_remove, |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 41964a71a036..93cf15efc717 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -89,7 +89,7 @@ static inline void lcd_unregister_fb(struct lcd_device *ld) | |||
89 | } | 89 | } |
90 | #endif /* CONFIG_FB */ | 90 | #endif /* CONFIG_FB */ |
91 | 91 | ||
92 | static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr, | 92 | static ssize_t lcd_power_show(struct device *dev, struct device_attribute *attr, |
93 | char *buf) | 93 | char *buf) |
94 | { | 94 | { |
95 | int rc; | 95 | int rc; |
@@ -105,7 +105,7 @@ static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr, | |||
105 | return rc; | 105 | return rc; |
106 | } | 106 | } |
107 | 107 | ||
108 | static ssize_t lcd_store_power(struct device *dev, | 108 | static ssize_t lcd_power_store(struct device *dev, |
109 | struct device_attribute *attr, const char *buf, size_t count) | 109 | struct device_attribute *attr, const char *buf, size_t count) |
110 | { | 110 | { |
111 | int rc; | 111 | int rc; |
@@ -128,8 +128,9 @@ static ssize_t lcd_store_power(struct device *dev, | |||
128 | 128 | ||
129 | return rc; | 129 | return rc; |
130 | } | 130 | } |
131 | static DEVICE_ATTR_RW(lcd_power); | ||
131 | 132 | ||
132 | static ssize_t lcd_show_contrast(struct device *dev, | 133 | static ssize_t contrast_show(struct device *dev, |
133 | struct device_attribute *attr, char *buf) | 134 | struct device_attribute *attr, char *buf) |
134 | { | 135 | { |
135 | int rc = -ENXIO; | 136 | int rc = -ENXIO; |
@@ -143,7 +144,7 @@ static ssize_t lcd_show_contrast(struct device *dev, | |||
143 | return rc; | 144 | return rc; |
144 | } | 145 | } |
145 | 146 | ||
146 | static ssize_t lcd_store_contrast(struct device *dev, | 147 | static ssize_t contrast_store(struct device *dev, |
147 | struct device_attribute *attr, const char *buf, size_t count) | 148 | struct device_attribute *attr, const char *buf, size_t count) |
148 | { | 149 | { |
149 | int rc; | 150 | int rc; |
@@ -166,14 +167,16 @@ static ssize_t lcd_store_contrast(struct device *dev, | |||
166 | 167 | ||
167 | return rc; | 168 | return rc; |
168 | } | 169 | } |
170 | static DEVICE_ATTR_RW(contrast); | ||
169 | 171 | ||
170 | static ssize_t lcd_show_max_contrast(struct device *dev, | 172 | static ssize_t max_contrast_show(struct device *dev, |
171 | struct device_attribute *attr, char *buf) | 173 | struct device_attribute *attr, char *buf) |
172 | { | 174 | { |
173 | struct lcd_device *ld = to_lcd_device(dev); | 175 | struct lcd_device *ld = to_lcd_device(dev); |
174 | 176 | ||
175 | return sprintf(buf, "%d\n", ld->props.max_contrast); | 177 | return sprintf(buf, "%d\n", ld->props.max_contrast); |
176 | } | 178 | } |
179 | static DEVICE_ATTR_RO(max_contrast); | ||
177 | 180 | ||
178 | static struct class *lcd_class; | 181 | static struct class *lcd_class; |
179 | 182 | ||
@@ -183,12 +186,13 @@ static void lcd_device_release(struct device *dev) | |||
183 | kfree(ld); | 186 | kfree(ld); |
184 | } | 187 | } |
185 | 188 | ||
186 | static struct device_attribute lcd_device_attributes[] = { | 189 | static struct attribute *lcd_device_attrs[] = { |
187 | __ATTR(lcd_power, 0644, lcd_show_power, lcd_store_power), | 190 | &dev_attr_lcd_power.attr, |
188 | __ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast), | 191 | &dev_attr_contrast.attr, |
189 | __ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), | 192 | &dev_attr_max_contrast.attr, |
190 | __ATTR_NULL, | 193 | NULL, |
191 | }; | 194 | }; |
195 | ATTRIBUTE_GROUPS(lcd_device); | ||
192 | 196 | ||
193 | /** | 197 | /** |
194 | * lcd_device_register - register a new object of lcd_device class. | 198 | * lcd_device_register - register a new object of lcd_device class. |
@@ -344,7 +348,7 @@ static int __init lcd_class_init(void) | |||
344 | return PTR_ERR(lcd_class); | 348 | return PTR_ERR(lcd_class); |
345 | } | 349 | } |
346 | 350 | ||
347 | lcd_class->dev_attrs = lcd_device_attributes; | 351 | lcd_class->dev_groups = lcd_device_groups; |
348 | return 0; | 352 | return 0; |
349 | } | 353 | } |
350 | 354 | ||
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index a0e1e02bdc2e..c0b41f13bd4a 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c | |||
@@ -246,7 +246,7 @@ static int lp855x_bl_update_status(struct backlight_device *bl) | |||
246 | { | 246 | { |
247 | struct lp855x *lp = bl_get_data(bl); | 247 | struct lp855x *lp = bl_get_data(bl); |
248 | 248 | ||
249 | if (bl->props.state & BL_CORE_SUSPENDED) | 249 | if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) |
250 | bl->props.brightness = 0; | 250 | bl->props.brightness = 0; |
251 | 251 | ||
252 | if (lp->mode == PWM_BASED) { | 252 | if (lp->mode == PWM_BASED) { |
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index 5ca11b066b7e..886e797f75f9 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c | |||
@@ -101,33 +101,37 @@ static const struct backlight_ops max8925_backlight_ops = { | |||
101 | .get_brightness = max8925_backlight_get_brightness, | 101 | .get_brightness = max8925_backlight_get_brightness, |
102 | }; | 102 | }; |
103 | 103 | ||
104 | #ifdef CONFIG_OF | 104 | static void max8925_backlight_dt_init(struct platform_device *pdev) |
105 | static int max8925_backlight_dt_init(struct platform_device *pdev, | ||
106 | struct max8925_backlight_pdata *pdata) | ||
107 | { | 105 | { |
108 | struct device_node *nproot = pdev->dev.parent->of_node, *np; | 106 | struct device_node *nproot = pdev->dev.parent->of_node, *np; |
109 | int dual_string; | 107 | struct max8925_backlight_pdata *pdata; |
108 | u32 val; | ||
109 | |||
110 | if (!nproot || !IS_ENABLED(CONFIG_OF)) | ||
111 | return; | ||
112 | |||
113 | pdata = devm_kzalloc(&pdev->dev, | ||
114 | sizeof(struct max8925_backlight_pdata), | ||
115 | GFP_KERNEL); | ||
116 | if (!pdata) | ||
117 | return; | ||
110 | 118 | ||
111 | if (!nproot) | ||
112 | return -ENODEV; | ||
113 | np = of_find_node_by_name(nproot, "backlight"); | 119 | np = of_find_node_by_name(nproot, "backlight"); |
114 | if (!np) { | 120 | if (!np) { |
115 | dev_err(&pdev->dev, "failed to find backlight node\n"); | 121 | dev_err(&pdev->dev, "failed to find backlight node\n"); |
116 | return -ENODEV; | 122 | return; |
117 | } | 123 | } |
118 | 124 | ||
119 | of_property_read_u32(np, "maxim,max8925-dual-string", &dual_string); | 125 | if (!of_property_read_u32(np, "maxim,max8925-dual-string", &val)) |
120 | pdata->dual_string = dual_string; | 126 | pdata->dual_string = val; |
121 | return 0; | 127 | |
128 | pdev->dev.platform_data = pdata; | ||
122 | } | 129 | } |
123 | #else | ||
124 | #define max8925_backlight_dt_init(x, y) (-1) | ||
125 | #endif | ||
126 | 130 | ||
127 | static int max8925_backlight_probe(struct platform_device *pdev) | 131 | static int max8925_backlight_probe(struct platform_device *pdev) |
128 | { | 132 | { |
129 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | 133 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); |
130 | struct max8925_backlight_pdata *pdata = pdev->dev.platform_data; | 134 | struct max8925_backlight_pdata *pdata; |
131 | struct max8925_backlight_data *data; | 135 | struct max8925_backlight_data *data; |
132 | struct backlight_device *bl; | 136 | struct backlight_device *bl; |
133 | struct backlight_properties props; | 137 | struct backlight_properties props; |
@@ -170,13 +174,10 @@ static int max8925_backlight_probe(struct platform_device *pdev) | |||
170 | platform_set_drvdata(pdev, bl); | 174 | platform_set_drvdata(pdev, bl); |
171 | 175 | ||
172 | value = 0; | 176 | value = 0; |
173 | if (pdev->dev.parent->of_node && !pdata) { | 177 | if (!pdev->dev.platform_data) |
174 | pdata = devm_kzalloc(&pdev->dev, | 178 | max8925_backlight_dt_init(pdev); |
175 | sizeof(struct max8925_backlight_pdata), | ||
176 | GFP_KERNEL); | ||
177 | max8925_backlight_dt_init(pdev, pdata); | ||
178 | } | ||
179 | 179 | ||
180 | pdata = pdev->dev.platform_data; | ||
180 | if (pdata) { | 181 | if (pdata) { |
181 | if (pdata->lxw_scl) | 182 | if (pdata->lxw_scl) |
182 | value |= (1 << 7); | 183 | value |= (1 << 7); |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 8c30603e0a86..846caab75a46 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -92,7 +92,8 @@ config DUMMY_CONSOLE_ROWS | |||
92 | 92 | ||
93 | config FRAMEBUFFER_CONSOLE | 93 | config FRAMEBUFFER_CONSOLE |
94 | tristate "Framebuffer Console support" | 94 | tristate "Framebuffer Console support" |
95 | depends on FB | 95 | depends on FB && !UML |
96 | select VT_HW_CONSOLE_BINDING | ||
96 | select CRC32 | 97 | select CRC32 |
97 | select FONT_SUPPORT | 98 | select FONT_SUPPORT |
98 | help | 99 | help |
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 0810939936f4..e030e17a83f2 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c | |||
@@ -131,29 +131,28 @@ | |||
131 | 131 | ||
132 | #define WSI_TIMEOUT 50 | 132 | #define WSI_TIMEOUT 50 |
133 | #define PALETTE_SIZE 256 | 133 | #define PALETTE_SIZE 256 |
134 | #define LEFT_MARGIN 64 | 134 | |
135 | #define RIGHT_MARGIN 64 | 135 | #define CLK_MIN_DIV 2 |
136 | #define UPPER_MARGIN 32 | 136 | #define CLK_MAX_DIV 255 |
137 | #define LOWER_MARGIN 32 | ||
138 | 137 | ||
139 | static void __iomem *da8xx_fb_reg_base; | 138 | static void __iomem *da8xx_fb_reg_base; |
140 | static struct resource *lcdc_regs; | ||
141 | static unsigned int lcd_revision; | 139 | static unsigned int lcd_revision; |
142 | static irq_handler_t lcdc_irq_handler; | 140 | static irq_handler_t lcdc_irq_handler; |
143 | static wait_queue_head_t frame_done_wq; | 141 | static wait_queue_head_t frame_done_wq; |
144 | static int frame_done_flag; | 142 | static int frame_done_flag; |
145 | 143 | ||
146 | static inline unsigned int lcdc_read(unsigned int addr) | 144 | static unsigned int lcdc_read(unsigned int addr) |
147 | { | 145 | { |
148 | return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr)); | 146 | return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr)); |
149 | } | 147 | } |
150 | 148 | ||
151 | static inline void lcdc_write(unsigned int val, unsigned int addr) | 149 | static void lcdc_write(unsigned int val, unsigned int addr) |
152 | { | 150 | { |
153 | __raw_writel(val, da8xx_fb_reg_base + (addr)); | 151 | __raw_writel(val, da8xx_fb_reg_base + (addr)); |
154 | } | 152 | } |
155 | 153 | ||
156 | struct da8xx_fb_par { | 154 | struct da8xx_fb_par { |
155 | struct device *dev; | ||
157 | resource_size_t p_palette_base; | 156 | resource_size_t p_palette_base; |
158 | unsigned char *v_palette_base; | 157 | unsigned char *v_palette_base; |
159 | dma_addr_t vram_phys; | 158 | dma_addr_t vram_phys; |
@@ -164,7 +163,6 @@ struct da8xx_fb_par { | |||
164 | struct clk *lcdc_clk; | 163 | struct clk *lcdc_clk; |
165 | int irq; | 164 | int irq; |
166 | unsigned int palette_sz; | 165 | unsigned int palette_sz; |
167 | unsigned int pxl_clk; | ||
168 | int blank; | 166 | int blank; |
169 | wait_queue_head_t vsync_wait; | 167 | wait_queue_head_t vsync_wait; |
170 | int vsync_flag; | 168 | int vsync_flag; |
@@ -178,29 +176,15 @@ struct da8xx_fb_par { | |||
178 | unsigned int which_dma_channel_done; | 176 | unsigned int which_dma_channel_done; |
179 | #ifdef CONFIG_CPU_FREQ | 177 | #ifdef CONFIG_CPU_FREQ |
180 | struct notifier_block freq_transition; | 178 | struct notifier_block freq_transition; |
181 | unsigned int lcd_fck_rate; | ||
182 | #endif | 179 | #endif |
180 | unsigned int lcdc_clk_rate; | ||
183 | void (*panel_power_ctrl)(int); | 181 | void (*panel_power_ctrl)(int); |
184 | u32 pseudo_palette[16]; | 182 | u32 pseudo_palette[16]; |
183 | struct fb_videomode mode; | ||
184 | struct lcd_ctrl_config cfg; | ||
185 | }; | 185 | }; |
186 | 186 | ||
187 | /* Variable Screen Information */ | 187 | static struct fb_var_screeninfo da8xx_fb_var; |
188 | static struct fb_var_screeninfo da8xx_fb_var = { | ||
189 | .xoffset = 0, | ||
190 | .yoffset = 0, | ||
191 | .transp = {0, 0, 0}, | ||
192 | .nonstd = 0, | ||
193 | .activate = 0, | ||
194 | .height = -1, | ||
195 | .width = -1, | ||
196 | .accel_flags = 0, | ||
197 | .left_margin = LEFT_MARGIN, | ||
198 | .right_margin = RIGHT_MARGIN, | ||
199 | .upper_margin = UPPER_MARGIN, | ||
200 | .lower_margin = LOWER_MARGIN, | ||
201 | .sync = 0, | ||
202 | .vmode = FB_VMODE_NONINTERLACED | ||
203 | }; | ||
204 | 188 | ||
205 | static struct fb_fix_screeninfo da8xx_fb_fix = { | 189 | static struct fb_fix_screeninfo da8xx_fb_fix = { |
206 | .id = "DA8xx FB Drv", | 190 | .id = "DA8xx FB Drv", |
@@ -219,7 +203,7 @@ static struct fb_videomode known_lcd_panels[] = { | |||
219 | .name = "Sharp_LCD035Q3DG01", | 203 | .name = "Sharp_LCD035Q3DG01", |
220 | .xres = 320, | 204 | .xres = 320, |
221 | .yres = 240, | 205 | .yres = 240, |
222 | .pixclock = 4608000, | 206 | .pixclock = KHZ2PICOS(4607), |
223 | .left_margin = 6, | 207 | .left_margin = 6, |
224 | .right_margin = 8, | 208 | .right_margin = 8, |
225 | .upper_margin = 2, | 209 | .upper_margin = 2, |
@@ -234,7 +218,7 @@ static struct fb_videomode known_lcd_panels[] = { | |||
234 | .name = "Sharp_LK043T1DG01", | 218 | .name = "Sharp_LK043T1DG01", |
235 | .xres = 480, | 219 | .xres = 480, |
236 | .yres = 272, | 220 | .yres = 272, |
237 | .pixclock = 7833600, | 221 | .pixclock = KHZ2PICOS(7833), |
238 | .left_margin = 2, | 222 | .left_margin = 2, |
239 | .right_margin = 2, | 223 | .right_margin = 2, |
240 | .upper_margin = 2, | 224 | .upper_margin = 2, |
@@ -249,7 +233,7 @@ static struct fb_videomode known_lcd_panels[] = { | |||
249 | .name = "SP10Q010", | 233 | .name = "SP10Q010", |
250 | .xres = 320, | 234 | .xres = 320, |
251 | .yres = 240, | 235 | .yres = 240, |
252 | .pixclock = 7833600, | 236 | .pixclock = KHZ2PICOS(7833), |
253 | .left_margin = 10, | 237 | .left_margin = 10, |
254 | .right_margin = 10, | 238 | .right_margin = 10, |
255 | .upper_margin = 10, | 239 | .upper_margin = 10, |
@@ -261,8 +245,13 @@ static struct fb_videomode known_lcd_panels[] = { | |||
261 | }, | 245 | }, |
262 | }; | 246 | }; |
263 | 247 | ||
248 | static bool da8xx_fb_is_raster_enabled(void) | ||
249 | { | ||
250 | return !!(lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE); | ||
251 | } | ||
252 | |||
264 | /* Enable the Raster Engine of the LCD Controller */ | 253 | /* Enable the Raster Engine of the LCD Controller */ |
265 | static inline void lcd_enable_raster(void) | 254 | static void lcd_enable_raster(void) |
266 | { | 255 | { |
267 | u32 reg; | 256 | u32 reg; |
268 | 257 | ||
@@ -284,7 +273,7 @@ static inline void lcd_enable_raster(void) | |||
284 | } | 273 | } |
285 | 274 | ||
286 | /* Disable the Raster Engine of the LCD Controller */ | 275 | /* Disable the Raster Engine of the LCD Controller */ |
287 | static inline void lcd_disable_raster(bool wait_for_frame_done) | 276 | static void lcd_disable_raster(enum da8xx_frame_complete wait_for_frame_done) |
288 | { | 277 | { |
289 | u32 reg; | 278 | u32 reg; |
290 | int ret; | 279 | int ret; |
@@ -296,7 +285,8 @@ static inline void lcd_disable_raster(bool wait_for_frame_done) | |||
296 | /* return if already disabled */ | 285 | /* return if already disabled */ |
297 | return; | 286 | return; |
298 | 287 | ||
299 | if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) { | 288 | if ((wait_for_frame_done == DA8XX_FRAME_WAIT) && |
289 | (lcd_revision == LCD_VERSION_2)) { | ||
300 | frame_done_flag = 0; | 290 | frame_done_flag = 0; |
301 | ret = wait_event_interruptible_timeout(frame_done_wq, | 291 | ret = wait_event_interruptible_timeout(frame_done_wq, |
302 | frame_done_flag != 0, | 292 | frame_done_flag != 0, |
@@ -331,7 +321,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par) | |||
331 | reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) | | 321 | reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) | |
332 | LCD_V2_END_OF_FRAME0_INT_ENA | | 322 | LCD_V2_END_OF_FRAME0_INT_ENA | |
333 | LCD_V2_END_OF_FRAME1_INT_ENA | | 323 | LCD_V2_END_OF_FRAME1_INT_ENA | |
334 | LCD_FRAME_DONE; | 324 | LCD_FRAME_DONE | LCD_SYNC_LOST; |
335 | lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG); | 325 | lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG); |
336 | } | 326 | } |
337 | reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; | 327 | reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; |
@@ -417,10 +407,25 @@ static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width, | |||
417 | u32 reg; | 407 | u32 reg; |
418 | 408 | ||
419 | reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf; | 409 | reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf; |
420 | reg |= ((back_porch & 0xff) << 24) | 410 | reg |= (((back_porch-1) & 0xff) << 24) |
421 | | ((front_porch & 0xff) << 16) | 411 | | (((front_porch-1) & 0xff) << 16) |
422 | | ((pulse_width & 0x3f) << 10); | 412 | | (((pulse_width-1) & 0x3f) << 10); |
423 | lcdc_write(reg, LCD_RASTER_TIMING_0_REG); | 413 | lcdc_write(reg, LCD_RASTER_TIMING_0_REG); |
414 | |||
415 | /* | ||
416 | * LCDC Version 2 adds some extra bits that increase the allowable | ||
417 | * size of the horizontal timing registers. | ||
418 | * remember that the registers use 0 to represent 1 so all values | ||
419 | * that get set into register need to be decremented by 1 | ||
420 | */ | ||
421 | if (lcd_revision == LCD_VERSION_2) { | ||
422 | /* Mask off the bits we want to change */ | ||
423 | reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & ~0x780000ff; | ||
424 | reg |= ((front_porch-1) & 0x300) >> 8; | ||
425 | reg |= ((back_porch-1) & 0x300) >> 4; | ||
426 | reg |= ((pulse_width-1) & 0x3c0) << 21; | ||
427 | lcdc_write(reg, LCD_RASTER_TIMING_2_REG); | ||
428 | } | ||
424 | } | 429 | } |
425 | 430 | ||
426 | static void lcd_cfg_vertical_sync(int back_porch, int pulse_width, | 431 | static void lcd_cfg_vertical_sync(int back_porch, int pulse_width, |
@@ -431,7 +436,7 @@ static void lcd_cfg_vertical_sync(int back_porch, int pulse_width, | |||
431 | reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff; | 436 | reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff; |
432 | reg |= ((back_porch & 0xff) << 24) | 437 | reg |= ((back_porch & 0xff) << 24) |
433 | | ((front_porch & 0xff) << 16) | 438 | | ((front_porch & 0xff) << 16) |
434 | | ((pulse_width & 0x3f) << 10); | 439 | | (((pulse_width-1) & 0x3f) << 10); |
435 | lcdc_write(reg, LCD_RASTER_TIMING_1_REG); | 440 | lcdc_write(reg, LCD_RASTER_TIMING_1_REG); |
436 | } | 441 | } |
437 | 442 | ||
@@ -488,12 +493,12 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg, | |||
488 | else | 493 | else |
489 | reg &= ~LCD_SYNC_EDGE; | 494 | reg &= ~LCD_SYNC_EDGE; |
490 | 495 | ||
491 | if (panel->sync & FB_SYNC_HOR_HIGH_ACT) | 496 | if ((panel->sync & FB_SYNC_HOR_HIGH_ACT) == 0) |
492 | reg |= LCD_INVERT_LINE_CLOCK; | 497 | reg |= LCD_INVERT_LINE_CLOCK; |
493 | else | 498 | else |
494 | reg &= ~LCD_INVERT_LINE_CLOCK; | 499 | reg &= ~LCD_INVERT_LINE_CLOCK; |
495 | 500 | ||
496 | if (panel->sync & FB_SYNC_VERT_HIGH_ACT) | 501 | if ((panel->sync & FB_SYNC_VERT_HIGH_ACT) == 0) |
497 | reg |= LCD_INVERT_FRAME_CLOCK; | 502 | reg |= LCD_INVERT_FRAME_CLOCK; |
498 | else | 503 | else |
499 | reg &= ~LCD_INVERT_FRAME_CLOCK; | 504 | reg &= ~LCD_INVERT_FRAME_CLOCK; |
@@ -565,10 +570,11 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, | |||
565 | break; | 570 | break; |
566 | case 24: | 571 | case 24: |
567 | reg |= LCD_V2_TFT_24BPP_MODE; | 572 | reg |= LCD_V2_TFT_24BPP_MODE; |
573 | break; | ||
568 | case 32: | 574 | case 32: |
575 | reg |= LCD_V2_TFT_24BPP_MODE; | ||
569 | reg |= LCD_V2_TFT_24BPP_UNPACK; | 576 | reg |= LCD_V2_TFT_24BPP_UNPACK; |
570 | break; | 577 | break; |
571 | |||
572 | case 8: | 578 | case 8: |
573 | par->palette_sz = 256 * 2; | 579 | par->palette_sz = 256 * 2; |
574 | break; | 580 | break; |
@@ -681,11 +687,8 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
681 | } | 687 | } |
682 | #undef CNVT_TOHW | 688 | #undef CNVT_TOHW |
683 | 689 | ||
684 | static void lcd_reset(struct da8xx_fb_par *par) | 690 | static void da8xx_fb_lcd_reset(void) |
685 | { | 691 | { |
686 | /* Disable the Raster if previously Enabled */ | ||
687 | lcd_disable_raster(false); | ||
688 | |||
689 | /* DMA has to be disabled */ | 692 | /* DMA has to be disabled */ |
690 | lcdc_write(0, LCD_DMA_CTRL_REG); | 693 | lcdc_write(0, LCD_DMA_CTRL_REG); |
691 | lcdc_write(0, LCD_RASTER_CTRL_REG); | 694 | lcdc_write(0, LCD_RASTER_CTRL_REG); |
@@ -698,21 +701,76 @@ static void lcd_reset(struct da8xx_fb_par *par) | |||
698 | } | 701 | } |
699 | } | 702 | } |
700 | 703 | ||
701 | static void lcd_calc_clk_divider(struct da8xx_fb_par *par) | 704 | static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par, |
705 | unsigned lcdc_clk_div, | ||
706 | unsigned lcdc_clk_rate) | ||
702 | { | 707 | { |
703 | unsigned int lcd_clk, div; | 708 | int ret; |
704 | 709 | ||
705 | lcd_clk = clk_get_rate(par->lcdc_clk); | 710 | if (par->lcdc_clk_rate != lcdc_clk_rate) { |
706 | div = lcd_clk / par->pxl_clk; | 711 | ret = clk_set_rate(par->lcdc_clk, lcdc_clk_rate); |
712 | if (IS_ERR_VALUE(ret)) { | ||
713 | dev_err(par->dev, | ||
714 | "unable to set clock rate at %u\n", | ||
715 | lcdc_clk_rate); | ||
716 | return ret; | ||
717 | } | ||
718 | par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); | ||
719 | } | ||
707 | 720 | ||
708 | /* Configure the LCD clock divisor. */ | 721 | /* Configure the LCD clock divisor. */ |
709 | lcdc_write(LCD_CLK_DIVISOR(div) | | 722 | lcdc_write(LCD_CLK_DIVISOR(lcdc_clk_div) | |
710 | (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); | 723 | (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); |
711 | 724 | ||
712 | if (lcd_revision == LCD_VERSION_2) | 725 | if (lcd_revision == LCD_VERSION_2) |
713 | lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN | | 726 | lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN | |
714 | LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG); | 727 | LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG); |
715 | 728 | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par, | ||
733 | unsigned pixclock, | ||
734 | unsigned *lcdc_clk_rate) | ||
735 | { | ||
736 | unsigned lcdc_clk_div; | ||
737 | |||
738 | pixclock = PICOS2KHZ(pixclock) * 1000; | ||
739 | |||
740 | *lcdc_clk_rate = par->lcdc_clk_rate; | ||
741 | |||
742 | if (pixclock < (*lcdc_clk_rate / CLK_MAX_DIV)) { | ||
743 | *lcdc_clk_rate = clk_round_rate(par->lcdc_clk, | ||
744 | pixclock * CLK_MAX_DIV); | ||
745 | lcdc_clk_div = CLK_MAX_DIV; | ||
746 | } else if (pixclock > (*lcdc_clk_rate / CLK_MIN_DIV)) { | ||
747 | *lcdc_clk_rate = clk_round_rate(par->lcdc_clk, | ||
748 | pixclock * CLK_MIN_DIV); | ||
749 | lcdc_clk_div = CLK_MIN_DIV; | ||
750 | } else { | ||
751 | lcdc_clk_div = *lcdc_clk_rate / pixclock; | ||
752 | } | ||
753 | |||
754 | return lcdc_clk_div; | ||
755 | } | ||
756 | |||
757 | static int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par, | ||
758 | struct fb_videomode *mode) | ||
759 | { | ||
760 | unsigned lcdc_clk_rate; | ||
761 | unsigned lcdc_clk_div = da8xx_fb_calc_clk_divider(par, mode->pixclock, | ||
762 | &lcdc_clk_rate); | ||
763 | |||
764 | return da8xx_fb_config_clk_divider(par, lcdc_clk_div, lcdc_clk_rate); | ||
765 | } | ||
766 | |||
767 | static unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par, | ||
768 | unsigned pixclock) | ||
769 | { | ||
770 | unsigned lcdc_clk_div, lcdc_clk_rate; | ||
771 | |||
772 | lcdc_clk_div = da8xx_fb_calc_clk_divider(par, pixclock, &lcdc_clk_rate); | ||
773 | return KHZ2PICOS(lcdc_clk_rate / (1000 * lcdc_clk_div)); | ||
716 | } | 774 | } |
717 | 775 | ||
718 | static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | 776 | static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, |
@@ -721,10 +779,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | |||
721 | u32 bpp; | 779 | u32 bpp; |
722 | int ret = 0; | 780 | int ret = 0; |
723 | 781 | ||
724 | lcd_reset(par); | 782 | ret = da8xx_fb_calc_config_clk_divider(par, panel); |
725 | 783 | if (IS_ERR_VALUE(ret)) { | |
726 | /* Calculate the divider */ | 784 | dev_err(par->dev, "unable to configure clock\n"); |
727 | lcd_calc_clk_divider(par); | 785 | return ret; |
786 | } | ||
728 | 787 | ||
729 | if (panel->sync & FB_SYNC_CLK_INVERT) | 788 | if (panel->sync & FB_SYNC_CLK_INVERT) |
730 | lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | | 789 | lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | |
@@ -739,10 +798,10 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | |||
739 | return ret; | 798 | return ret; |
740 | 799 | ||
741 | /* Configure the vertical and horizontal sync properties. */ | 800 | /* Configure the vertical and horizontal sync properties. */ |
742 | lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len, | 801 | lcd_cfg_vertical_sync(panel->upper_margin, panel->vsync_len, |
743 | panel->upper_margin); | 802 | panel->lower_margin); |
744 | lcd_cfg_horizontal_sync(panel->right_margin, panel->hsync_len, | 803 | lcd_cfg_horizontal_sync(panel->left_margin, panel->hsync_len, |
745 | panel->left_margin); | 804 | panel->right_margin); |
746 | 805 | ||
747 | /* Configure for disply */ | 806 | /* Configure for disply */ |
748 | ret = lcd_cfg_display(cfg, panel); | 807 | ret = lcd_cfg_display(cfg, panel); |
@@ -773,7 +832,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) | |||
773 | u32 stat = lcdc_read(LCD_MASKED_STAT_REG); | 832 | u32 stat = lcdc_read(LCD_MASKED_STAT_REG); |
774 | 833 | ||
775 | if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { | 834 | if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { |
776 | lcd_disable_raster(false); | 835 | lcd_disable_raster(DA8XX_FRAME_NOWAIT); |
777 | lcdc_write(stat, LCD_MASKED_STAT_REG); | 836 | lcdc_write(stat, LCD_MASKED_STAT_REG); |
778 | lcd_enable_raster(); | 837 | lcd_enable_raster(); |
779 | } else if (stat & LCD_PL_LOAD_DONE) { | 838 | } else if (stat & LCD_PL_LOAD_DONE) { |
@@ -783,7 +842,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) | |||
783 | * interrupt via the following write to the status register. If | 842 | * interrupt via the following write to the status register. If |
784 | * this is done after then one gets multiple PL done interrupts. | 843 | * this is done after then one gets multiple PL done interrupts. |
785 | */ | 844 | */ |
786 | lcd_disable_raster(false); | 845 | lcd_disable_raster(DA8XX_FRAME_NOWAIT); |
787 | 846 | ||
788 | lcdc_write(stat, LCD_MASKED_STAT_REG); | 847 | lcdc_write(stat, LCD_MASKED_STAT_REG); |
789 | 848 | ||
@@ -836,7 +895,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) | |||
836 | u32 reg_ras; | 895 | u32 reg_ras; |
837 | 896 | ||
838 | if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { | 897 | if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { |
839 | lcd_disable_raster(false); | 898 | lcd_disable_raster(DA8XX_FRAME_NOWAIT); |
840 | lcdc_write(stat, LCD_STAT_REG); | 899 | lcdc_write(stat, LCD_STAT_REG); |
841 | lcd_enable_raster(); | 900 | lcd_enable_raster(); |
842 | } else if (stat & LCD_PL_LOAD_DONE) { | 901 | } else if (stat & LCD_PL_LOAD_DONE) { |
@@ -846,7 +905,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) | |||
846 | * interrupt via the following write to the status register. If | 905 | * interrupt via the following write to the status register. If |
847 | * this is done after then one gets multiple PL done interrupts. | 906 | * this is done after then one gets multiple PL done interrupts. |
848 | */ | 907 | */ |
849 | lcd_disable_raster(false); | 908 | lcd_disable_raster(DA8XX_FRAME_NOWAIT); |
850 | 909 | ||
851 | lcdc_write(stat, LCD_STAT_REG); | 910 | lcdc_write(stat, LCD_STAT_REG); |
852 | 911 | ||
@@ -888,6 +947,9 @@ static int fb_check_var(struct fb_var_screeninfo *var, | |||
888 | struct fb_info *info) | 947 | struct fb_info *info) |
889 | { | 948 | { |
890 | int err = 0; | 949 | int err = 0; |
950 | struct da8xx_fb_par *par = info->par; | ||
951 | int bpp = var->bits_per_pixel >> 3; | ||
952 | unsigned long line_size = var->xres_virtual * bpp; | ||
891 | 953 | ||
892 | if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1) | 954 | if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1) |
893 | return -EINVAL; | 955 | return -EINVAL; |
@@ -955,6 +1017,23 @@ static int fb_check_var(struct fb_var_screeninfo *var, | |||
955 | var->green.msb_right = 0; | 1017 | var->green.msb_right = 0; |
956 | var->blue.msb_right = 0; | 1018 | var->blue.msb_right = 0; |
957 | var->transp.msb_right = 0; | 1019 | var->transp.msb_right = 0; |
1020 | |||
1021 | if (line_size * var->yres_virtual > par->vram_size) | ||
1022 | var->yres_virtual = par->vram_size / line_size; | ||
1023 | |||
1024 | if (var->yres > var->yres_virtual) | ||
1025 | var->yres = var->yres_virtual; | ||
1026 | |||
1027 | if (var->xres > var->xres_virtual) | ||
1028 | var->xres = var->xres_virtual; | ||
1029 | |||
1030 | if (var->xres + var->xoffset > var->xres_virtual) | ||
1031 | var->xoffset = var->xres_virtual - var->xres; | ||
1032 | if (var->yres + var->yoffset > var->yres_virtual) | ||
1033 | var->yoffset = var->yres_virtual - var->yres; | ||
1034 | |||
1035 | var->pixclock = da8xx_fb_round_clk(par, var->pixclock); | ||
1036 | |||
958 | return err; | 1037 | return err; |
959 | } | 1038 | } |
960 | 1039 | ||
@@ -966,10 +1045,10 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, | |||
966 | 1045 | ||
967 | par = container_of(nb, struct da8xx_fb_par, freq_transition); | 1046 | par = container_of(nb, struct da8xx_fb_par, freq_transition); |
968 | if (val == CPUFREQ_POSTCHANGE) { | 1047 | if (val == CPUFREQ_POSTCHANGE) { |
969 | if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { | 1048 | if (par->lcdc_clk_rate != clk_get_rate(par->lcdc_clk)) { |
970 | par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); | 1049 | par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); |
971 | lcd_disable_raster(true); | 1050 | lcd_disable_raster(DA8XX_FRAME_WAIT); |
972 | lcd_calc_clk_divider(par); | 1051 | da8xx_fb_calc_config_clk_divider(par, &par->mode); |
973 | if (par->blank == FB_BLANK_UNBLANK) | 1052 | if (par->blank == FB_BLANK_UNBLANK) |
974 | lcd_enable_raster(); | 1053 | lcd_enable_raster(); |
975 | } | 1054 | } |
@@ -978,7 +1057,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, | |||
978 | return 0; | 1057 | return 0; |
979 | } | 1058 | } |
980 | 1059 | ||
981 | static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) | 1060 | static int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) |
982 | { | 1061 | { |
983 | par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition; | 1062 | par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition; |
984 | 1063 | ||
@@ -986,7 +1065,7 @@ static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) | |||
986 | CPUFREQ_TRANSITION_NOTIFIER); | 1065 | CPUFREQ_TRANSITION_NOTIFIER); |
987 | } | 1066 | } |
988 | 1067 | ||
989 | static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par) | 1068 | static void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par) |
990 | { | 1069 | { |
991 | cpufreq_unregister_notifier(&par->freq_transition, | 1070 | cpufreq_unregister_notifier(&par->freq_transition, |
992 | CPUFREQ_TRANSITION_NOTIFIER); | 1071 | CPUFREQ_TRANSITION_NOTIFIER); |
@@ -1006,7 +1085,7 @@ static int fb_remove(struct platform_device *dev) | |||
1006 | if (par->panel_power_ctrl) | 1085 | if (par->panel_power_ctrl) |
1007 | par->panel_power_ctrl(0); | 1086 | par->panel_power_ctrl(0); |
1008 | 1087 | ||
1009 | lcd_disable_raster(true); | 1088 | lcd_disable_raster(DA8XX_FRAME_WAIT); |
1010 | lcdc_write(0, LCD_RASTER_CTRL_REG); | 1089 | lcdc_write(0, LCD_RASTER_CTRL_REG); |
1011 | 1090 | ||
1012 | /* disable DMA */ | 1091 | /* disable DMA */ |
@@ -1018,12 +1097,9 @@ static int fb_remove(struct platform_device *dev) | |||
1018 | par->p_palette_base); | 1097 | par->p_palette_base); |
1019 | dma_free_coherent(NULL, par->vram_size, par->vram_virt, | 1098 | dma_free_coherent(NULL, par->vram_size, par->vram_virt, |
1020 | par->vram_phys); | 1099 | par->vram_phys); |
1021 | free_irq(par->irq, par); | ||
1022 | pm_runtime_put_sync(&dev->dev); | 1100 | pm_runtime_put_sync(&dev->dev); |
1023 | pm_runtime_disable(&dev->dev); | 1101 | pm_runtime_disable(&dev->dev); |
1024 | framebuffer_release(info); | 1102 | framebuffer_release(info); |
1025 | iounmap(da8xx_fb_reg_base); | ||
1026 | release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); | ||
1027 | 1103 | ||
1028 | } | 1104 | } |
1029 | return 0; | 1105 | return 0; |
@@ -1122,7 +1198,7 @@ static int cfb_blank(int blank, struct fb_info *info) | |||
1122 | if (par->panel_power_ctrl) | 1198 | if (par->panel_power_ctrl) |
1123 | par->panel_power_ctrl(0); | 1199 | par->panel_power_ctrl(0); |
1124 | 1200 | ||
1125 | lcd_disable_raster(true); | 1201 | lcd_disable_raster(DA8XX_FRAME_WAIT); |
1126 | break; | 1202 | break; |
1127 | default: | 1203 | default: |
1128 | ret = -EINVAL; | 1204 | ret = -EINVAL; |
@@ -1183,9 +1259,50 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var, | |||
1183 | return ret; | 1259 | return ret; |
1184 | } | 1260 | } |
1185 | 1261 | ||
1262 | static int da8xxfb_set_par(struct fb_info *info) | ||
1263 | { | ||
1264 | struct da8xx_fb_par *par = info->par; | ||
1265 | int ret; | ||
1266 | bool raster = da8xx_fb_is_raster_enabled(); | ||
1267 | |||
1268 | if (raster) | ||
1269 | lcd_disable_raster(DA8XX_FRAME_WAIT); | ||
1270 | |||
1271 | fb_var_to_videomode(&par->mode, &info->var); | ||
1272 | |||
1273 | par->cfg.bpp = info->var.bits_per_pixel; | ||
1274 | |||
1275 | info->fix.visual = (par->cfg.bpp <= 8) ? | ||
1276 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
1277 | info->fix.line_length = (par->mode.xres * par->cfg.bpp) / 8; | ||
1278 | |||
1279 | ret = lcd_init(par, &par->cfg, &par->mode); | ||
1280 | if (ret < 0) { | ||
1281 | dev_err(par->dev, "lcd init failed\n"); | ||
1282 | return ret; | ||
1283 | } | ||
1284 | |||
1285 | par->dma_start = info->fix.smem_start + | ||
1286 | info->var.yoffset * info->fix.line_length + | ||
1287 | info->var.xoffset * info->var.bits_per_pixel / 8; | ||
1288 | par->dma_end = par->dma_start + | ||
1289 | info->var.yres * info->fix.line_length - 1; | ||
1290 | |||
1291 | lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); | ||
1292 | lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); | ||
1293 | lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); | ||
1294 | lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); | ||
1295 | |||
1296 | if (raster) | ||
1297 | lcd_enable_raster(); | ||
1298 | |||
1299 | return 0; | ||
1300 | } | ||
1301 | |||
1186 | static struct fb_ops da8xx_fb_ops = { | 1302 | static struct fb_ops da8xx_fb_ops = { |
1187 | .owner = THIS_MODULE, | 1303 | .owner = THIS_MODULE, |
1188 | .fb_check_var = fb_check_var, | 1304 | .fb_check_var = fb_check_var, |
1305 | .fb_set_par = da8xxfb_set_par, | ||
1189 | .fb_setcolreg = fb_setcolreg, | 1306 | .fb_setcolreg = fb_setcolreg, |
1190 | .fb_pan_display = da8xx_pan_display, | 1307 | .fb_pan_display = da8xx_pan_display, |
1191 | .fb_ioctl = fb_ioctl, | 1308 | .fb_ioctl = fb_ioctl, |
@@ -1195,33 +1312,38 @@ static struct fb_ops da8xx_fb_ops = { | |||
1195 | .fb_blank = cfb_blank, | 1312 | .fb_blank = cfb_blank, |
1196 | }; | 1313 | }; |
1197 | 1314 | ||
1198 | /* Calculate and return pixel clock period in pico seconds */ | 1315 | static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev) |
1199 | static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par) | ||
1200 | { | 1316 | { |
1201 | unsigned int lcd_clk, div; | 1317 | struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; |
1202 | unsigned int configured_pix_clk; | 1318 | struct fb_videomode *lcdc_info; |
1203 | unsigned long long pix_clk_period_picosec = 1000000000000ULL; | 1319 | int i; |
1204 | 1320 | ||
1205 | lcd_clk = clk_get_rate(par->lcdc_clk); | 1321 | for (i = 0, lcdc_info = known_lcd_panels; |
1206 | div = lcd_clk / par->pxl_clk; | 1322 | i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) { |
1207 | configured_pix_clk = (lcd_clk / div); | 1323 | if (strcmp(fb_pdata->type, lcdc_info->name) == 0) |
1324 | break; | ||
1325 | } | ||
1208 | 1326 | ||
1209 | do_div(pix_clk_period_picosec, configured_pix_clk); | 1327 | if (i == ARRAY_SIZE(known_lcd_panels)) { |
1328 | dev_err(&dev->dev, "no panel found\n"); | ||
1329 | return NULL; | ||
1330 | } | ||
1331 | dev_info(&dev->dev, "found %s panel\n", lcdc_info->name); | ||
1210 | 1332 | ||
1211 | return pix_clk_period_picosec; | 1333 | return lcdc_info; |
1212 | } | 1334 | } |
1213 | 1335 | ||
1214 | static int fb_probe(struct platform_device *device) | 1336 | static int fb_probe(struct platform_device *device) |
1215 | { | 1337 | { |
1216 | struct da8xx_lcdc_platform_data *fb_pdata = | 1338 | struct da8xx_lcdc_platform_data *fb_pdata = |
1217 | device->dev.platform_data; | 1339 | device->dev.platform_data; |
1340 | static struct resource *lcdc_regs; | ||
1218 | struct lcd_ctrl_config *lcd_cfg; | 1341 | struct lcd_ctrl_config *lcd_cfg; |
1219 | struct fb_videomode *lcdc_info; | 1342 | struct fb_videomode *lcdc_info; |
1220 | struct fb_info *da8xx_fb_info; | 1343 | struct fb_info *da8xx_fb_info; |
1221 | struct clk *fb_clk = NULL; | ||
1222 | struct da8xx_fb_par *par; | 1344 | struct da8xx_fb_par *par; |
1223 | resource_size_t len; | 1345 | struct clk *tmp_lcdc_clk; |
1224 | int ret, i; | 1346 | int ret; |
1225 | unsigned long ulcm; | 1347 | unsigned long ulcm; |
1226 | 1348 | ||
1227 | if (fb_pdata == NULL) { | 1349 | if (fb_pdata == NULL) { |
@@ -1229,30 +1351,19 @@ static int fb_probe(struct platform_device *device) | |||
1229 | return -ENOENT; | 1351 | return -ENOENT; |
1230 | } | 1352 | } |
1231 | 1353 | ||
1232 | lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0); | 1354 | lcdc_info = da8xx_fb_get_videomode(device); |
1233 | if (!lcdc_regs) { | 1355 | if (lcdc_info == NULL) |
1234 | dev_err(&device->dev, | 1356 | return -ENODEV; |
1235 | "Can not get memory resource for LCD controller\n"); | ||
1236 | return -ENOENT; | ||
1237 | } | ||
1238 | |||
1239 | len = resource_size(lcdc_regs); | ||
1240 | 1357 | ||
1241 | lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name); | 1358 | lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0); |
1242 | if (!lcdc_regs) | 1359 | da8xx_fb_reg_base = devm_ioremap_resource(&device->dev, lcdc_regs); |
1243 | return -EBUSY; | 1360 | if (IS_ERR(da8xx_fb_reg_base)) |
1244 | 1361 | return PTR_ERR(da8xx_fb_reg_base); | |
1245 | da8xx_fb_reg_base = ioremap(lcdc_regs->start, len); | ||
1246 | if (!da8xx_fb_reg_base) { | ||
1247 | ret = -EBUSY; | ||
1248 | goto err_request_mem; | ||
1249 | } | ||
1250 | 1362 | ||
1251 | fb_clk = clk_get(&device->dev, "fck"); | 1363 | tmp_lcdc_clk = devm_clk_get(&device->dev, "fck"); |
1252 | if (IS_ERR(fb_clk)) { | 1364 | if (IS_ERR(tmp_lcdc_clk)) { |
1253 | dev_err(&device->dev, "Can not get device clock\n"); | 1365 | dev_err(&device->dev, "Can not get device clock\n"); |
1254 | ret = -ENODEV; | 1366 | return PTR_ERR(tmp_lcdc_clk); |
1255 | goto err_ioremap; | ||
1256 | } | 1367 | } |
1257 | 1368 | ||
1258 | pm_runtime_enable(&device->dev); | 1369 | pm_runtime_enable(&device->dev); |
@@ -1275,22 +1386,12 @@ static int fb_probe(struct platform_device *device) | |||
1275 | break; | 1386 | break; |
1276 | } | 1387 | } |
1277 | 1388 | ||
1278 | for (i = 0, lcdc_info = known_lcd_panels; | 1389 | lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; |
1279 | i < ARRAY_SIZE(known_lcd_panels); | ||
1280 | i++, lcdc_info++) { | ||
1281 | if (strcmp(fb_pdata->type, lcdc_info->name) == 0) | ||
1282 | break; | ||
1283 | } | ||
1284 | 1390 | ||
1285 | if (i == ARRAY_SIZE(known_lcd_panels)) { | 1391 | if (!lcd_cfg) { |
1286 | dev_err(&device->dev, "GLCD: No valid panel found\n"); | 1392 | ret = -EINVAL; |
1287 | ret = -ENODEV; | ||
1288 | goto err_pm_runtime_disable; | 1393 | goto err_pm_runtime_disable; |
1289 | } else | 1394 | } |
1290 | dev_info(&device->dev, "GLCD: Found %s panel\n", | ||
1291 | fb_pdata->type); | ||
1292 | |||
1293 | lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; | ||
1294 | 1395 | ||
1295 | da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par), | 1396 | da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par), |
1296 | &device->dev); | 1397 | &device->dev); |
@@ -1301,21 +1402,18 @@ static int fb_probe(struct platform_device *device) | |||
1301 | } | 1402 | } |
1302 | 1403 | ||
1303 | par = da8xx_fb_info->par; | 1404 | par = da8xx_fb_info->par; |
1304 | par->lcdc_clk = fb_clk; | 1405 | par->dev = &device->dev; |
1305 | #ifdef CONFIG_CPU_FREQ | 1406 | par->lcdc_clk = tmp_lcdc_clk; |
1306 | par->lcd_fck_rate = clk_get_rate(fb_clk); | 1407 | par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); |
1307 | #endif | ||
1308 | par->pxl_clk = lcdc_info->pixclock; | ||
1309 | if (fb_pdata->panel_power_ctrl) { | 1408 | if (fb_pdata->panel_power_ctrl) { |
1310 | par->panel_power_ctrl = fb_pdata->panel_power_ctrl; | 1409 | par->panel_power_ctrl = fb_pdata->panel_power_ctrl; |
1311 | par->panel_power_ctrl(1); | 1410 | par->panel_power_ctrl(1); |
1312 | } | 1411 | } |
1313 | 1412 | ||
1314 | if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { | 1413 | fb_videomode_to_var(&da8xx_fb_var, lcdc_info); |
1315 | dev_err(&device->dev, "lcd_init failed\n"); | 1414 | par->cfg = *lcd_cfg; |
1316 | ret = -EFAULT; | 1415 | |
1317 | goto err_release_fb; | 1416 | da8xx_fb_lcd_reset(); |
1318 | } | ||
1319 | 1417 | ||
1320 | /* allocate frame buffer */ | 1418 | /* allocate frame buffer */ |
1321 | par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp; | 1419 | par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp; |
@@ -1363,27 +1461,10 @@ static int fb_probe(struct platform_device *device) | |||
1363 | goto err_release_pl_mem; | 1461 | goto err_release_pl_mem; |
1364 | } | 1462 | } |
1365 | 1463 | ||
1366 | /* Initialize par */ | ||
1367 | da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; | ||
1368 | |||
1369 | da8xx_fb_var.xres = lcdc_info->xres; | ||
1370 | da8xx_fb_var.xres_virtual = lcdc_info->xres; | ||
1371 | |||
1372 | da8xx_fb_var.yres = lcdc_info->yres; | ||
1373 | da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS; | ||
1374 | |||
1375 | da8xx_fb_var.grayscale = | 1464 | da8xx_fb_var.grayscale = |
1376 | lcd_cfg->panel_shade == MONOCHROME ? 1 : 0; | 1465 | lcd_cfg->panel_shade == MONOCHROME ? 1 : 0; |
1377 | da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp; | 1466 | da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp; |
1378 | 1467 | ||
1379 | da8xx_fb_var.hsync_len = lcdc_info->hsync_len; | ||
1380 | da8xx_fb_var.vsync_len = lcdc_info->vsync_len; | ||
1381 | da8xx_fb_var.right_margin = lcdc_info->right_margin; | ||
1382 | da8xx_fb_var.left_margin = lcdc_info->left_margin; | ||
1383 | da8xx_fb_var.lower_margin = lcdc_info->lower_margin; | ||
1384 | da8xx_fb_var.upper_margin = lcdc_info->upper_margin; | ||
1385 | da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par); | ||
1386 | |||
1387 | /* Initialize fbinfo */ | 1468 | /* Initialize fbinfo */ |
1388 | da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT; | 1469 | da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT; |
1389 | da8xx_fb_info->fix = da8xx_fb_fix; | 1470 | da8xx_fb_info->fix = da8xx_fb_fix; |
@@ -1433,8 +1514,8 @@ static int fb_probe(struct platform_device *device) | |||
1433 | lcdc_irq_handler = lcdc_irq_handler_rev02; | 1514 | lcdc_irq_handler = lcdc_irq_handler_rev02; |
1434 | } | 1515 | } |
1435 | 1516 | ||
1436 | ret = request_irq(par->irq, lcdc_irq_handler, 0, | 1517 | ret = devm_request_irq(&device->dev, par->irq, lcdc_irq_handler, 0, |
1437 | DRIVER_NAME, par); | 1518 | DRIVER_NAME, par); |
1438 | if (ret) | 1519 | if (ret) |
1439 | goto irq_freq; | 1520 | goto irq_freq; |
1440 | return 0; | 1521 | return 0; |
@@ -1463,12 +1544,6 @@ err_pm_runtime_disable: | |||
1463 | pm_runtime_put_sync(&device->dev); | 1544 | pm_runtime_put_sync(&device->dev); |
1464 | pm_runtime_disable(&device->dev); | 1545 | pm_runtime_disable(&device->dev); |
1465 | 1546 | ||
1466 | err_ioremap: | ||
1467 | iounmap(da8xx_fb_reg_base); | ||
1468 | |||
1469 | err_request_mem: | ||
1470 | release_mem_region(lcdc_regs->start, len); | ||
1471 | |||
1472 | return ret; | 1547 | return ret; |
1473 | } | 1548 | } |
1474 | 1549 | ||
@@ -1546,7 +1621,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state) | |||
1546 | par->panel_power_ctrl(0); | 1621 | par->panel_power_ctrl(0); |
1547 | 1622 | ||
1548 | fb_set_suspend(info, 1); | 1623 | fb_set_suspend(info, 1); |
1549 | lcd_disable_raster(true); | 1624 | lcd_disable_raster(DA8XX_FRAME_WAIT); |
1550 | lcd_context_save(); | 1625 | lcd_context_save(); |
1551 | pm_runtime_put_sync(&dev->dev); | 1626 | pm_runtime_put_sync(&dev->dev); |
1552 | console_unlock(); | 1627 | console_unlock(); |
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index 50fe668c6172..7f9ff75d0db2 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/dmi.h> | 15 | #include <linux/dmi.h> |
16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
17 | #include <video/vga.h> | 17 | #include <video/vga.h> |
18 | #include <asm/sysfb.h> | ||
18 | 19 | ||
19 | static bool request_mem_succeeded = false; | 20 | static bool request_mem_succeeded = false; |
20 | 21 | ||
@@ -38,223 +39,6 @@ static struct fb_fix_screeninfo efifb_fix = { | |||
38 | .visual = FB_VISUAL_TRUECOLOR, | 39 | .visual = FB_VISUAL_TRUECOLOR, |
39 | }; | 40 | }; |
40 | 41 | ||
41 | enum { | ||
42 | M_I17, /* 17-Inch iMac */ | ||
43 | M_I20, /* 20-Inch iMac */ | ||
44 | M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ | ||
45 | M_I24, /* 24-Inch iMac */ | ||
46 | M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ | ||
47 | M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ | ||
48 | M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ | ||
49 | M_MINI, /* Mac Mini */ | ||
50 | M_MINI_3_1, /* Mac Mini, 3,1th gen */ | ||
51 | M_MINI_4_1, /* Mac Mini, 4,1th gen */ | ||
52 | M_MB, /* MacBook */ | ||
53 | M_MB_2, /* MacBook, 2nd rev. */ | ||
54 | M_MB_3, /* MacBook, 3rd rev. */ | ||
55 | M_MB_5_1, /* MacBook, 5th rev. */ | ||
56 | M_MB_6_1, /* MacBook, 6th rev. */ | ||
57 | M_MB_7_1, /* MacBook, 7th rev. */ | ||
58 | M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ | ||
59 | M_MBA, /* MacBook Air */ | ||
60 | M_MBA_3, /* Macbook Air, 3rd rev */ | ||
61 | M_MBP, /* MacBook Pro */ | ||
62 | M_MBP_2, /* MacBook Pro 2nd gen */ | ||
63 | M_MBP_2_2, /* MacBook Pro 2,2nd gen */ | ||
64 | M_MBP_SR, /* MacBook Pro (Santa Rosa) */ | ||
65 | M_MBP_4, /* MacBook Pro, 4th gen */ | ||
66 | M_MBP_5_1, /* MacBook Pro, 5,1th gen */ | ||
67 | M_MBP_5_2, /* MacBook Pro, 5,2th gen */ | ||
68 | M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ | ||
69 | M_MBP_6_1, /* MacBook Pro, 6,1th gen */ | ||
70 | M_MBP_6_2, /* MacBook Pro, 6,2th gen */ | ||
71 | M_MBP_7_1, /* MacBook Pro, 7,1th gen */ | ||
72 | M_MBP_8_2, /* MacBook Pro, 8,2nd gen */ | ||
73 | M_UNKNOWN /* placeholder */ | ||
74 | }; | ||
75 | |||
76 | #define OVERRIDE_NONE 0x0 | ||
77 | #define OVERRIDE_BASE 0x1 | ||
78 | #define OVERRIDE_STRIDE 0x2 | ||
79 | #define OVERRIDE_HEIGHT 0x4 | ||
80 | #define OVERRIDE_WIDTH 0x8 | ||
81 | |||
82 | static struct efifb_dmi_info { | ||
83 | char *optname; | ||
84 | unsigned long base; | ||
85 | int stride; | ||
86 | int width; | ||
87 | int height; | ||
88 | int flags; | ||
89 | } dmi_list[] __initdata = { | ||
90 | [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
91 | [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ | ||
92 | [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
93 | [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ | ||
94 | [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
95 | [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, | ||
96 | [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, | ||
97 | [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, | ||
98 | [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, | ||
99 | [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
100 | [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
101 | [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
102 | [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
103 | [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
104 | [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
105 | /* 11" Macbook Air 3,1 passes the wrong stride */ | ||
106 | [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, | ||
107 | [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
108 | [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ | ||
109 | [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
110 | [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
111 | [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
112 | [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
113 | [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
114 | [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, | ||
115 | [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, | ||
116 | [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, | ||
117 | [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, | ||
118 | [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, | ||
119 | [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } | ||
120 | }; | ||
121 | |||
122 | static int set_system(const struct dmi_system_id *id); | ||
123 | |||
124 | #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ | ||
125 | { set_system, name, { \ | ||
126 | DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ | ||
127 | DMI_MATCH(DMI_PRODUCT_NAME, name) }, \ | ||
128 | &dmi_list[enumid] } | ||
129 | |||
130 | static const struct dmi_system_id dmi_system_table[] __initconst = { | ||
131 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), | ||
132 | /* At least one of these two will be right; maybe both? */ | ||
133 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), | ||
134 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), | ||
135 | /* At least one of these two will be right; maybe both? */ | ||
136 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), | ||
137 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), | ||
138 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), | ||
139 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), | ||
140 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), | ||
141 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), | ||
142 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), | ||
143 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), | ||
144 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), | ||
145 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), | ||
146 | /* At least one of these two will be right; maybe both? */ | ||
147 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), | ||
148 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), | ||
149 | /* At least one of these two will be right; maybe both? */ | ||
150 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), | ||
151 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), | ||
152 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), | ||
153 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), | ||
154 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), | ||
155 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), | ||
156 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), | ||
157 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3), | ||
158 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), | ||
159 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), | ||
160 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), | ||
161 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), | ||
162 | EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), | ||
163 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), | ||
164 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), | ||
165 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), | ||
166 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), | ||
167 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), | ||
168 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), | ||
169 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), | ||
170 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), | ||
171 | EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2), | ||
172 | {}, | ||
173 | }; | ||
174 | |||
175 | #define choose_value(dmivalue, fwvalue, field, flags) ({ \ | ||
176 | typeof(fwvalue) _ret_ = fwvalue; \ | ||
177 | if ((flags) & (field)) \ | ||
178 | _ret_ = dmivalue; \ | ||
179 | else if ((fwvalue) == 0) \ | ||
180 | _ret_ = dmivalue; \ | ||
181 | _ret_; \ | ||
182 | }) | ||
183 | |||
184 | static int set_system(const struct dmi_system_id *id) | ||
185 | { | ||
186 | struct efifb_dmi_info *info = id->driver_data; | ||
187 | |||
188 | if (info->base == 0 && info->height == 0 && info->width == 0 | ||
189 | && info->stride == 0) | ||
190 | return 0; | ||
191 | |||
192 | /* Trust the bootloader over the DMI tables */ | ||
193 | if (screen_info.lfb_base == 0) { | ||
194 | #if defined(CONFIG_PCI) | ||
195 | struct pci_dev *dev = NULL; | ||
196 | int found_bar = 0; | ||
197 | #endif | ||
198 | if (info->base) { | ||
199 | screen_info.lfb_base = choose_value(info->base, | ||
200 | screen_info.lfb_base, OVERRIDE_BASE, | ||
201 | info->flags); | ||
202 | |||
203 | #if defined(CONFIG_PCI) | ||
204 | /* make sure that the address in the table is actually | ||
205 | * on a VGA device's PCI BAR */ | ||
206 | |||
207 | for_each_pci_dev(dev) { | ||
208 | int i; | ||
209 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
210 | continue; | ||
211 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
212 | resource_size_t start, end; | ||
213 | |||
214 | start = pci_resource_start(dev, i); | ||
215 | if (start == 0) | ||
216 | break; | ||
217 | end = pci_resource_end(dev, i); | ||
218 | if (screen_info.lfb_base >= start && | ||
219 | screen_info.lfb_base < end) { | ||
220 | found_bar = 1; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | if (!found_bar) | ||
225 | screen_info.lfb_base = 0; | ||
226 | #endif | ||
227 | } | ||
228 | } | ||
229 | if (screen_info.lfb_base) { | ||
230 | screen_info.lfb_linelength = choose_value(info->stride, | ||
231 | screen_info.lfb_linelength, OVERRIDE_STRIDE, | ||
232 | info->flags); | ||
233 | screen_info.lfb_width = choose_value(info->width, | ||
234 | screen_info.lfb_width, OVERRIDE_WIDTH, | ||
235 | info->flags); | ||
236 | screen_info.lfb_height = choose_value(info->height, | ||
237 | screen_info.lfb_height, OVERRIDE_HEIGHT, | ||
238 | info->flags); | ||
239 | if (screen_info.orig_video_isVGA == 0) | ||
240 | screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; | ||
241 | } else { | ||
242 | screen_info.lfb_linelength = 0; | ||
243 | screen_info.lfb_width = 0; | ||
244 | screen_info.lfb_height = 0; | ||
245 | screen_info.orig_video_isVGA = 0; | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " | ||
250 | "(%dx%d, stride %d)\n", id->ident, | ||
251 | screen_info.lfb_base, screen_info.lfb_width, | ||
252 | screen_info.lfb_height, screen_info.lfb_linelength); | ||
253 | |||
254 | |||
255 | return 1; | ||
256 | } | ||
257 | |||
258 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, | 42 | static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, |
259 | unsigned blue, unsigned transp, | 43 | unsigned blue, unsigned transp, |
260 | struct fb_info *info) | 44 | struct fb_info *info) |
@@ -288,6 +72,7 @@ static void efifb_destroy(struct fb_info *info) | |||
288 | if (request_mem_succeeded) | 72 | if (request_mem_succeeded) |
289 | release_mem_region(info->apertures->ranges[0].base, | 73 | release_mem_region(info->apertures->ranges[0].base, |
290 | info->apertures->ranges[0].size); | 74 | info->apertures->ranges[0].size); |
75 | fb_dealloc_cmap(&info->cmap); | ||
291 | framebuffer_release(info); | 76 | framebuffer_release(info); |
292 | } | 77 | } |
293 | 78 | ||
@@ -312,7 +97,7 @@ void vga_set_default_device(struct pci_dev *pdev) | |||
312 | default_vga = pdev; | 97 | default_vga = pdev; |
313 | } | 98 | } |
314 | 99 | ||
315 | static int __init efifb_setup(char *options) | 100 | static int efifb_setup(char *options) |
316 | { | 101 | { |
317 | char *this_opt; | 102 | char *this_opt; |
318 | int i; | 103 | int i; |
@@ -323,12 +108,12 @@ static int __init efifb_setup(char *options) | |||
323 | if (!*this_opt) continue; | 108 | if (!*this_opt) continue; |
324 | 109 | ||
325 | for (i = 0; i < M_UNKNOWN; i++) { | 110 | for (i = 0; i < M_UNKNOWN; i++) { |
326 | if (!strcmp(this_opt, dmi_list[i].optname) && | 111 | if (!strcmp(this_opt, efifb_dmi_list[i].optname) && |
327 | dmi_list[i].base != 0) { | 112 | efifb_dmi_list[i].base != 0) { |
328 | screen_info.lfb_base = dmi_list[i].base; | 113 | screen_info.lfb_base = efifb_dmi_list[i].base; |
329 | screen_info.lfb_linelength = dmi_list[i].stride; | 114 | screen_info.lfb_linelength = efifb_dmi_list[i].stride; |
330 | screen_info.lfb_width = dmi_list[i].width; | 115 | screen_info.lfb_width = efifb_dmi_list[i].width; |
331 | screen_info.lfb_height = dmi_list[i].height; | 116 | screen_info.lfb_height = efifb_dmi_list[i].height; |
332 | } | 117 | } |
333 | } | 118 | } |
334 | if (!strncmp(this_opt, "base:", 5)) | 119 | if (!strncmp(this_opt, "base:", 5)) |
@@ -369,13 +154,28 @@ static int __init efifb_setup(char *options) | |||
369 | return 0; | 154 | return 0; |
370 | } | 155 | } |
371 | 156 | ||
372 | static int __init efifb_probe(struct platform_device *dev) | 157 | static int efifb_probe(struct platform_device *dev) |
373 | { | 158 | { |
374 | struct fb_info *info; | 159 | struct fb_info *info; |
375 | int err; | 160 | int err; |
376 | unsigned int size_vmode; | 161 | unsigned int size_vmode; |
377 | unsigned int size_remap; | 162 | unsigned int size_remap; |
378 | unsigned int size_total; | 163 | unsigned int size_total; |
164 | char *option = NULL; | ||
165 | |||
166 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) | ||
167 | return -ENODEV; | ||
168 | |||
169 | if (fb_get_options("efifb", &option)) | ||
170 | return -ENODEV; | ||
171 | efifb_setup(option); | ||
172 | |||
173 | /* We don't get linelength from UGA Draw Protocol, only from | ||
174 | * EFI Graphics Protocol. So if it's not in DMI, and it's not | ||
175 | * passed in from the user, we really can't use the framebuffer. | ||
176 | */ | ||
177 | if (!screen_info.lfb_linelength) | ||
178 | return -ENODEV; | ||
379 | 179 | ||
380 | if (!screen_info.lfb_depth) | 180 | if (!screen_info.lfb_depth) |
381 | screen_info.lfb_depth = 32; | 181 | screen_info.lfb_depth = 32; |
@@ -539,55 +339,12 @@ err_release_mem: | |||
539 | } | 339 | } |
540 | 340 | ||
541 | static struct platform_driver efifb_driver = { | 341 | static struct platform_driver efifb_driver = { |
542 | .driver = { | 342 | .driver = { |
543 | .name = "efifb", | 343 | .name = "efi-framebuffer", |
344 | .owner = THIS_MODULE, | ||
544 | }, | 345 | }, |
346 | .probe = efifb_probe, | ||
545 | }; | 347 | }; |
546 | 348 | ||
547 | static struct platform_device efifb_device = { | 349 | module_platform_driver(efifb_driver); |
548 | .name = "efifb", | ||
549 | }; | ||
550 | |||
551 | static int __init efifb_init(void) | ||
552 | { | ||
553 | int ret; | ||
554 | char *option = NULL; | ||
555 | |||
556 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || | ||
557 | !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) | ||
558 | dmi_check_system(dmi_system_table); | ||
559 | |||
560 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) | ||
561 | return -ENODEV; | ||
562 | |||
563 | if (fb_get_options("efifb", &option)) | ||
564 | return -ENODEV; | ||
565 | efifb_setup(option); | ||
566 | |||
567 | /* We don't get linelength from UGA Draw Protocol, only from | ||
568 | * EFI Graphics Protocol. So if it's not in DMI, and it's not | ||
569 | * passed in from the user, we really can't use the framebuffer. | ||
570 | */ | ||
571 | if (!screen_info.lfb_linelength) | ||
572 | return -ENODEV; | ||
573 | |||
574 | ret = platform_device_register(&efifb_device); | ||
575 | if (ret) | ||
576 | return ret; | ||
577 | |||
578 | /* | ||
579 | * This is not just an optimization. We will interfere | ||
580 | * with a real driver if we get reprobed, so don't allow | ||
581 | * it. | ||
582 | */ | ||
583 | ret = platform_driver_probe(&efifb_driver, efifb_probe); | ||
584 | if (ret) { | ||
585 | platform_device_unregister(&efifb_device); | ||
586 | return ret; | ||
587 | } | ||
588 | |||
589 | return ret; | ||
590 | } | ||
591 | module_init(efifb_init); | ||
592 | |||
593 | MODULE_LICENSE("GPL"); | 350 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c index 15c5abd408dc..c148d06540c1 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c +++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <video/exynos_mipi_dsim.h> | 27 | #include <video/exynos_mipi_dsim.h> |
28 | 28 | ||
29 | #include "exynos_mipi_dsi_regs.h" | 29 | #include "exynos_mipi_dsi_regs.h" |
30 | #include "exynos_mipi_dsi_lowlevel.h" | ||
30 | 31 | ||
31 | void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim) | 32 | void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim) |
32 | { | 33 | { |
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index 5c3960da755a..f89245b8ba8e 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c | |||
@@ -285,13 +285,8 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) | |||
285 | rc = -ENODEV; | 285 | rc = -ENODEV; |
286 | goto out; | 286 | goto out; |
287 | } | 287 | } |
288 | if (cmap->start < 0 || (!info->fbops->fb_setcolreg && | 288 | |
289 | !info->fbops->fb_setcmap)) { | ||
290 | rc = -EINVAL; | ||
291 | goto out1; | ||
292 | } | ||
293 | rc = fb_set_cmap(&umap, info); | 289 | rc = fb_set_cmap(&umap, info); |
294 | out1: | ||
295 | unlock_fb_info(info); | 290 | unlock_fb_info(info); |
296 | out: | 291 | out: |
297 | fb_dealloc_cmap(&umap); | 292 | fb_dealloc_cmap(&umap); |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 36e1fe21b9b5..dacaf74256a3 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -43,8 +43,12 @@ | |||
43 | #define FBPIXMAPSIZE (1024 * 8) | 43 | #define FBPIXMAPSIZE (1024 * 8) |
44 | 44 | ||
45 | static DEFINE_MUTEX(registration_lock); | 45 | static DEFINE_MUTEX(registration_lock); |
46 | |||
46 | struct fb_info *registered_fb[FB_MAX] __read_mostly; | 47 | struct fb_info *registered_fb[FB_MAX] __read_mostly; |
48 | EXPORT_SYMBOL(registered_fb); | ||
49 | |||
47 | int num_registered_fb __read_mostly; | 50 | int num_registered_fb __read_mostly; |
51 | EXPORT_SYMBOL(num_registered_fb); | ||
48 | 52 | ||
49 | static struct fb_info *get_fb_info(unsigned int idx) | 53 | static struct fb_info *get_fb_info(unsigned int idx) |
50 | { | 54 | { |
@@ -182,6 +186,7 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size | |||
182 | 186 | ||
183 | return addr; | 187 | return addr; |
184 | } | 188 | } |
189 | EXPORT_SYMBOL(fb_get_buffer_offset); | ||
185 | 190 | ||
186 | #ifdef CONFIG_LOGO | 191 | #ifdef CONFIG_LOGO |
187 | 192 | ||
@@ -669,6 +674,7 @@ int fb_show_logo(struct fb_info *info, int rotate) | |||
669 | int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; } | 674 | int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; } |
670 | int fb_show_logo(struct fb_info *info, int rotate) { return 0; } | 675 | int fb_show_logo(struct fb_info *info, int rotate) { return 0; } |
671 | #endif /* CONFIG_LOGO */ | 676 | #endif /* CONFIG_LOGO */ |
677 | EXPORT_SYMBOL(fb_show_logo); | ||
672 | 678 | ||
673 | static void *fb_seq_start(struct seq_file *m, loff_t *pos) | 679 | static void *fb_seq_start(struct seq_file *m, loff_t *pos) |
674 | { | 680 | { |
@@ -909,6 +915,7 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) | |||
909 | info->var.vmode &= ~FB_VMODE_YWRAP; | 915 | info->var.vmode &= ~FB_VMODE_YWRAP; |
910 | return 0; | 916 | return 0; |
911 | } | 917 | } |
918 | EXPORT_SYMBOL(fb_pan_display); | ||
912 | 919 | ||
913 | static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, | 920 | static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, |
914 | u32 activate) | 921 | u32 activate) |
@@ -1042,6 +1049,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) | |||
1042 | done: | 1049 | done: |
1043 | return ret; | 1050 | return ret; |
1044 | } | 1051 | } |
1052 | EXPORT_SYMBOL(fb_set_var); | ||
1045 | 1053 | ||
1046 | int | 1054 | int |
1047 | fb_blank(struct fb_info *info, int blank) | 1055 | fb_blank(struct fb_info *info, int blank) |
@@ -1073,6 +1081,7 @@ fb_blank(struct fb_info *info, int blank) | |||
1073 | 1081 | ||
1074 | return ret; | 1082 | return ret; |
1075 | } | 1083 | } |
1084 | EXPORT_SYMBOL(fb_blank); | ||
1076 | 1085 | ||
1077 | static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, | 1086 | static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, |
1078 | unsigned long arg) | 1087 | unsigned long arg) |
@@ -1745,6 +1754,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1745 | 1754 | ||
1746 | return ret; | 1755 | return ret; |
1747 | } | 1756 | } |
1757 | EXPORT_SYMBOL(register_framebuffer); | ||
1748 | 1758 | ||
1749 | /** | 1759 | /** |
1750 | * unregister_framebuffer - releases a frame buffer device | 1760 | * unregister_framebuffer - releases a frame buffer device |
@@ -1773,6 +1783,7 @@ unregister_framebuffer(struct fb_info *fb_info) | |||
1773 | 1783 | ||
1774 | return ret; | 1784 | return ret; |
1775 | } | 1785 | } |
1786 | EXPORT_SYMBOL(unregister_framebuffer); | ||
1776 | 1787 | ||
1777 | /** | 1788 | /** |
1778 | * fb_set_suspend - low level driver signals suspend | 1789 | * fb_set_suspend - low level driver signals suspend |
@@ -1796,6 +1807,7 @@ void fb_set_suspend(struct fb_info *info, int state) | |||
1796 | fb_notifier_call_chain(FB_EVENT_RESUME, &event); | 1807 | fb_notifier_call_chain(FB_EVENT_RESUME, &event); |
1797 | } | 1808 | } |
1798 | } | 1809 | } |
1810 | EXPORT_SYMBOL(fb_set_suspend); | ||
1799 | 1811 | ||
1800 | /** | 1812 | /** |
1801 | * fbmem_init - init frame buffer subsystem | 1813 | * fbmem_init - init frame buffer subsystem |
@@ -1912,6 +1924,7 @@ int fb_get_options(const char *name, char **option) | |||
1912 | 1924 | ||
1913 | return retval; | 1925 | return retval; |
1914 | } | 1926 | } |
1927 | EXPORT_SYMBOL(fb_get_options); | ||
1915 | 1928 | ||
1916 | #ifndef MODULE | 1929 | #ifndef MODULE |
1917 | /** | 1930 | /** |
@@ -1959,20 +1972,4 @@ static int __init video_setup(char *options) | |||
1959 | __setup("video=", video_setup); | 1972 | __setup("video=", video_setup); |
1960 | #endif | 1973 | #endif |
1961 | 1974 | ||
1962 | /* | ||
1963 | * Visible symbols for modules | ||
1964 | */ | ||
1965 | |||
1966 | EXPORT_SYMBOL(register_framebuffer); | ||
1967 | EXPORT_SYMBOL(unregister_framebuffer); | ||
1968 | EXPORT_SYMBOL(num_registered_fb); | ||
1969 | EXPORT_SYMBOL(registered_fb); | ||
1970 | EXPORT_SYMBOL(fb_show_logo); | ||
1971 | EXPORT_SYMBOL(fb_set_var); | ||
1972 | EXPORT_SYMBOL(fb_blank); | ||
1973 | EXPORT_SYMBOL(fb_pan_display); | ||
1974 | EXPORT_SYMBOL(fb_get_buffer_offset); | ||
1975 | EXPORT_SYMBOL(fb_set_suspend); | ||
1976 | EXPORT_SYMBOL(fb_get_options); | ||
1977 | |||
1978 | MODULE_LICENSE("GPL"); | 1975 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index 40178338b619..9e758a8f890d 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c | |||
@@ -22,6 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/bitops.h> | 24 | #include <linux/bitops.h> |
25 | #include <linux/bug.h> | ||
25 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
26 | #include <linux/export.h> | 27 | #include <linux/export.h> |
27 | #include <linux/hdmi.h> | 28 | #include <linux/hdmi.h> |
@@ -52,7 +53,7 @@ int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame) | |||
52 | 53 | ||
53 | frame->type = HDMI_INFOFRAME_TYPE_AVI; | 54 | frame->type = HDMI_INFOFRAME_TYPE_AVI; |
54 | frame->version = 2; | 55 | frame->version = 2; |
55 | frame->length = 13; | 56 | frame->length = HDMI_AVI_INFOFRAME_SIZE; |
56 | 57 | ||
57 | return 0; | 58 | return 0; |
58 | } | 59 | } |
@@ -83,7 +84,7 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, | |||
83 | if (size < length) | 84 | if (size < length) |
84 | return -ENOSPC; | 85 | return -ENOSPC; |
85 | 86 | ||
86 | memset(buffer, 0, length); | 87 | memset(buffer, 0, size); |
87 | 88 | ||
88 | ptr[0] = frame->type; | 89 | ptr[0] = frame->type; |
89 | ptr[1] = frame->version; | 90 | ptr[1] = frame->version; |
@@ -95,13 +96,18 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, | |||
95 | 96 | ||
96 | ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3); | 97 | ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3); |
97 | 98 | ||
98 | if (frame->active_info_valid) | 99 | /* |
100 | * Data byte 1, bit 4 has to be set if we provide the active format | ||
101 | * aspect ratio | ||
102 | */ | ||
103 | if (frame->active_aspect & 0xf) | ||
99 | ptr[0] |= BIT(4); | 104 | ptr[0] |= BIT(4); |
100 | 105 | ||
101 | if (frame->horizontal_bar_valid) | 106 | /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */ |
107 | if (frame->top_bar || frame->bottom_bar) | ||
102 | ptr[0] |= BIT(3); | 108 | ptr[0] |= BIT(3); |
103 | 109 | ||
104 | if (frame->vertical_bar_valid) | 110 | if (frame->left_bar || frame->right_bar) |
105 | ptr[0] |= BIT(2); | 111 | ptr[0] |= BIT(2); |
106 | 112 | ||
107 | ptr[1] = ((frame->colorimetry & 0x3) << 6) | | 113 | ptr[1] = ((frame->colorimetry & 0x3) << 6) | |
@@ -151,7 +157,7 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, | |||
151 | 157 | ||
152 | frame->type = HDMI_INFOFRAME_TYPE_SPD; | 158 | frame->type = HDMI_INFOFRAME_TYPE_SPD; |
153 | frame->version = 1; | 159 | frame->version = 1; |
154 | frame->length = 25; | 160 | frame->length = HDMI_SPD_INFOFRAME_SIZE; |
155 | 161 | ||
156 | strncpy(frame->vendor, vendor, sizeof(frame->vendor)); | 162 | strncpy(frame->vendor, vendor, sizeof(frame->vendor)); |
157 | strncpy(frame->product, product, sizeof(frame->product)); | 163 | strncpy(frame->product, product, sizeof(frame->product)); |
@@ -185,7 +191,7 @@ ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, | |||
185 | if (size < length) | 191 | if (size < length) |
186 | return -ENOSPC; | 192 | return -ENOSPC; |
187 | 193 | ||
188 | memset(buffer, 0, length); | 194 | memset(buffer, 0, size); |
189 | 195 | ||
190 | ptr[0] = frame->type; | 196 | ptr[0] = frame->type; |
191 | ptr[1] = frame->version; | 197 | ptr[1] = frame->version; |
@@ -218,7 +224,7 @@ int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame) | |||
218 | 224 | ||
219 | frame->type = HDMI_INFOFRAME_TYPE_AUDIO; | 225 | frame->type = HDMI_INFOFRAME_TYPE_AUDIO; |
220 | frame->version = 1; | 226 | frame->version = 1; |
221 | frame->length = 10; | 227 | frame->length = HDMI_AUDIO_INFOFRAME_SIZE; |
222 | 228 | ||
223 | return 0; | 229 | return 0; |
224 | } | 230 | } |
@@ -250,7 +256,7 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, | |||
250 | if (size < length) | 256 | if (size < length) |
251 | return -ENOSPC; | 257 | return -ENOSPC; |
252 | 258 | ||
253 | memset(buffer, 0, length); | 259 | memset(buffer, 0, size); |
254 | 260 | ||
255 | if (frame->channels >= 2) | 261 | if (frame->channels >= 2) |
256 | channels = frame->channels - 1; | 262 | channels = frame->channels - 1; |
@@ -282,9 +288,33 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, | |||
282 | EXPORT_SYMBOL(hdmi_audio_infoframe_pack); | 288 | EXPORT_SYMBOL(hdmi_audio_infoframe_pack); |
283 | 289 | ||
284 | /** | 290 | /** |
285 | * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary | 291 | * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe |
286 | * buffer | ||
287 | * @frame: HDMI vendor infoframe | 292 | * @frame: HDMI vendor infoframe |
293 | * | ||
294 | * Returns 0 on success or a negative error code on failure. | ||
295 | */ | ||
296 | int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) | ||
297 | { | ||
298 | memset(frame, 0, sizeof(*frame)); | ||
299 | |||
300 | frame->type = HDMI_INFOFRAME_TYPE_VENDOR; | ||
301 | frame->version = 1; | ||
302 | |||
303 | frame->oui = HDMI_IEEE_OUI; | ||
304 | |||
305 | /* | ||
306 | * 0 is a valid value for s3d_struct, so we use a special "not set" | ||
307 | * value | ||
308 | */ | ||
309 | frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID; | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | EXPORT_SYMBOL(hdmi_vendor_infoframe_init); | ||
314 | |||
315 | /** | ||
316 | * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer | ||
317 | * @frame: HDMI infoframe | ||
288 | * @buffer: destination buffer | 318 | * @buffer: destination buffer |
289 | * @size: size of buffer | 319 | * @size: size of buffer |
290 | * | 320 | * |
@@ -297,27 +327,110 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_pack); | |||
297 | * error code on failure. | 327 | * error code on failure. |
298 | */ | 328 | */ |
299 | ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, | 329 | ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, |
300 | void *buffer, size_t size) | 330 | void *buffer, size_t size) |
301 | { | 331 | { |
302 | u8 *ptr = buffer; | 332 | u8 *ptr = buffer; |
303 | size_t length; | 333 | size_t length; |
304 | 334 | ||
335 | /* empty info frame */ | ||
336 | if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID) | ||
337 | return -EINVAL; | ||
338 | |||
339 | /* only one of those can be supplied */ | ||
340 | if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) | ||
341 | return -EINVAL; | ||
342 | |||
343 | /* for side by side (half) we also need to provide 3D_Ext_Data */ | ||
344 | if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) | ||
345 | frame->length = 6; | ||
346 | else | ||
347 | frame->length = 5; | ||
348 | |||
305 | length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; | 349 | length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; |
306 | 350 | ||
307 | if (size < length) | 351 | if (size < length) |
308 | return -ENOSPC; | 352 | return -ENOSPC; |
309 | 353 | ||
310 | memset(buffer, 0, length); | 354 | memset(buffer, 0, size); |
311 | 355 | ||
312 | ptr[0] = frame->type; | 356 | ptr[0] = frame->type; |
313 | ptr[1] = frame->version; | 357 | ptr[1] = frame->version; |
314 | ptr[2] = frame->length; | 358 | ptr[2] = frame->length; |
315 | ptr[3] = 0; /* checksum */ | 359 | ptr[3] = 0; /* checksum */ |
316 | 360 | ||
317 | memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length); | 361 | /* HDMI OUI */ |
362 | ptr[4] = 0x03; | ||
363 | ptr[5] = 0x0c; | ||
364 | ptr[6] = 0x00; | ||
365 | |||
366 | if (frame->vic) { | ||
367 | ptr[7] = 0x1 << 5; /* video format */ | ||
368 | ptr[8] = frame->vic; | ||
369 | } else { | ||
370 | ptr[7] = 0x2 << 5; /* video format */ | ||
371 | ptr[8] = (frame->s3d_struct & 0xf) << 4; | ||
372 | if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) | ||
373 | ptr[9] = (frame->s3d_ext_data & 0xf) << 4; | ||
374 | } | ||
318 | 375 | ||
319 | hdmi_infoframe_checksum(buffer, length); | 376 | hdmi_infoframe_checksum(buffer, length); |
320 | 377 | ||
321 | return length; | 378 | return length; |
322 | } | 379 | } |
323 | EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); | 380 | EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); |
381 | |||
382 | /* | ||
383 | * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer | ||
384 | */ | ||
385 | static ssize_t | ||
386 | hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, | ||
387 | void *buffer, size_t size) | ||
388 | { | ||
389 | /* we only know about HDMI vendor infoframes */ | ||
390 | if (frame->any.oui != HDMI_IEEE_OUI) | ||
391 | return -EINVAL; | ||
392 | |||
393 | return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size); | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer | ||
398 | * @frame: HDMI infoframe | ||
399 | * @buffer: destination buffer | ||
400 | * @size: size of buffer | ||
401 | * | ||
402 | * Packs the information contained in the @frame structure into a binary | ||
403 | * representation that can be written into the corresponding controller | ||
404 | * registers. Also computes the checksum as required by section 5.3.5 of | ||
405 | * the HDMI 1.4 specification. | ||
406 | * | ||
407 | * Returns the number of bytes packed into the binary buffer or a negative | ||
408 | * error code on failure. | ||
409 | */ | ||
410 | ssize_t | ||
411 | hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) | ||
412 | { | ||
413 | ssize_t length; | ||
414 | |||
415 | switch (frame->any.type) { | ||
416 | case HDMI_INFOFRAME_TYPE_AVI: | ||
417 | length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size); | ||
418 | break; | ||
419 | case HDMI_INFOFRAME_TYPE_SPD: | ||
420 | length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size); | ||
421 | break; | ||
422 | case HDMI_INFOFRAME_TYPE_AUDIO: | ||
423 | length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size); | ||
424 | break; | ||
425 | case HDMI_INFOFRAME_TYPE_VENDOR: | ||
426 | length = hdmi_vendor_any_infoframe_pack(&frame->vendor, | ||
427 | buffer, size); | ||
428 | break; | ||
429 | default: | ||
430 | WARN(1, "Bad infoframe type %d\n", frame->any.type); | ||
431 | length = -EINVAL; | ||
432 | } | ||
433 | |||
434 | return length; | ||
435 | } | ||
436 | EXPORT_SYMBOL(hdmi_infoframe_pack); | ||
diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c index d4d2c5fe2488..8ac99b87c07e 100644 --- a/drivers/video/hyperv_fb.c +++ b/drivers/video/hyperv_fb.c | |||
@@ -825,5 +825,4 @@ module_init(hvfb_drv_init); | |||
825 | module_exit(hvfb_drv_exit); | 825 | module_exit(hvfb_drv_exit); |
826 | 826 | ||
827 | MODULE_LICENSE("GPL"); | 827 | MODULE_LICENSE("GPL"); |
828 | MODULE_VERSION(HV_DRV_VERSION); | ||
829 | MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver"); | 828 | MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver"); |
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 401a56e250bd..245652911650 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c | |||
@@ -2029,10 +2029,9 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm | |||
2029 | return -1; | 2029 | return -1; |
2030 | } | 2030 | } |
2031 | 2031 | ||
2032 | minfo = kmalloc(sizeof(*minfo), GFP_KERNEL); | 2032 | minfo = kzalloc(sizeof(*minfo), GFP_KERNEL); |
2033 | if (!minfo) | 2033 | if (!minfo) |
2034 | return -1; | 2034 | return -1; |
2035 | memset(minfo, 0, sizeof(*minfo)); | ||
2036 | 2035 | ||
2037 | minfo->pcidev = pdev; | 2036 | minfo->pcidev = pdev; |
2038 | minfo->dead = 0; | 2037 | minfo->dead = 0; |
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 3ba37713b1f9..d250ed0f806d 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/clk.h> | 46 | #include <linux/clk.h> |
47 | #include <linux/dma-mapping.h> | 47 | #include <linux/dma-mapping.h> |
48 | #include <linux/io.h> | 48 | #include <linux/io.h> |
49 | #include <linux/pinctrl/consumer.h> | ||
50 | #include <linux/fb.h> | 49 | #include <linux/fb.h> |
51 | #include <linux/regulator/consumer.h> | 50 | #include <linux/regulator/consumer.h> |
52 | #include <video/of_display_timing.h> | 51 | #include <video/of_display_timing.h> |
@@ -239,24 +238,6 @@ static const struct fb_bitfield def_rgb565[] = { | |||
239 | } | 238 | } |
240 | }; | 239 | }; |
241 | 240 | ||
242 | static const struct fb_bitfield def_rgb666[] = { | ||
243 | [RED] = { | ||
244 | .offset = 16, | ||
245 | .length = 6, | ||
246 | }, | ||
247 | [GREEN] = { | ||
248 | .offset = 8, | ||
249 | .length = 6, | ||
250 | }, | ||
251 | [BLUE] = { | ||
252 | .offset = 0, | ||
253 | .length = 6, | ||
254 | }, | ||
255 | [TRANSP] = { /* no support for transparency */ | ||
256 | .length = 0, | ||
257 | } | ||
258 | }; | ||
259 | |||
260 | static const struct fb_bitfield def_rgb888[] = { | 241 | static const struct fb_bitfield def_rgb888[] = { |
261 | [RED] = { | 242 | [RED] = { |
262 | .offset = 16, | 243 | .offset = 16, |
@@ -309,9 +290,6 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var, | |||
309 | break; | 290 | break; |
310 | case STMLCDIF_16BIT: | 291 | case STMLCDIF_16BIT: |
311 | case STMLCDIF_18BIT: | 292 | case STMLCDIF_18BIT: |
312 | /* 24 bit to 18 bit mapping */ | ||
313 | rgb = def_rgb666; | ||
314 | break; | ||
315 | case STMLCDIF_24BIT: | 293 | case STMLCDIF_24BIT: |
316 | /* real 24 bit */ | 294 | /* real 24 bit */ |
317 | rgb = def_rgb888; | 295 | rgb = def_rgb888; |
@@ -453,11 +431,6 @@ static int mxsfb_set_par(struct fb_info *fb_info) | |||
453 | return -EINVAL; | 431 | return -EINVAL; |
454 | case STMLCDIF_16BIT: | 432 | case STMLCDIF_16BIT: |
455 | case STMLCDIF_18BIT: | 433 | case STMLCDIF_18BIT: |
456 | /* 24 bit to 18 bit mapping */ | ||
457 | ctrl |= CTRL_DF24; /* ignore the upper 2 bits in | ||
458 | * each colour component | ||
459 | */ | ||
460 | break; | ||
461 | case STMLCDIF_24BIT: | 434 | case STMLCDIF_24BIT: |
462 | /* real 24 bit */ | 435 | /* real 24 bit */ |
463 | break; | 436 | break; |
@@ -877,18 +850,11 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
877 | struct mxsfb_info *host; | 850 | struct mxsfb_info *host; |
878 | struct fb_info *fb_info; | 851 | struct fb_info *fb_info; |
879 | struct fb_modelist *modelist; | 852 | struct fb_modelist *modelist; |
880 | struct pinctrl *pinctrl; | ||
881 | int ret; | 853 | int ret; |
882 | 854 | ||
883 | if (of_id) | 855 | if (of_id) |
884 | pdev->id_entry = of_id->data; | 856 | pdev->id_entry = of_id->data; |
885 | 857 | ||
886 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
887 | if (!res) { | ||
888 | dev_err(&pdev->dev, "Cannot get memory IO resource\n"); | ||
889 | return -ENODEV; | ||
890 | } | ||
891 | |||
892 | fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev); | 858 | fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev); |
893 | if (!fb_info) { | 859 | if (!fb_info) { |
894 | dev_err(&pdev->dev, "Failed to allocate fbdev\n"); | 860 | dev_err(&pdev->dev, "Failed to allocate fbdev\n"); |
@@ -897,6 +863,7 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
897 | 863 | ||
898 | host = to_imxfb_host(fb_info); | 864 | host = to_imxfb_host(fb_info); |
899 | 865 | ||
866 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
900 | host->base = devm_ioremap_resource(&pdev->dev, res); | 867 | host->base = devm_ioremap_resource(&pdev->dev, res); |
901 | if (IS_ERR(host->base)) { | 868 | if (IS_ERR(host->base)) { |
902 | ret = PTR_ERR(host->base); | 869 | ret = PTR_ERR(host->base); |
@@ -908,12 +875,6 @@ static int mxsfb_probe(struct platform_device *pdev) | |||
908 | 875 | ||
909 | host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; | 876 | host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; |
910 | 877 | ||
911 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||
912 | if (IS_ERR(pinctrl)) { | ||
913 | ret = PTR_ERR(pinctrl); | ||
914 | goto fb_release; | ||
915 | } | ||
916 | |||
917 | host->clk = devm_clk_get(&host->pdev->dev, NULL); | 878 | host->clk = devm_clk_get(&host->pdev->dev, NULL); |
918 | if (IS_ERR(host->clk)) { | 879 | if (IS_ERR(host->clk)) { |
919 | ret = PTR_ERR(host->clk); | 880 | ret = PTR_ERR(host->clk); |
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c index 8c527e5b293c..796e5112ceee 100644 --- a/drivers/video/nuc900fb.c +++ b/drivers/video/nuc900fb.c | |||
@@ -587,8 +587,7 @@ static int nuc900fb_probe(struct platform_device *pdev) | |||
587 | fbinfo->flags = FBINFO_FLAG_DEFAULT; | 587 | fbinfo->flags = FBINFO_FLAG_DEFAULT; |
588 | fbinfo->pseudo_palette = &fbi->pseudo_pal; | 588 | fbinfo->pseudo_palette = &fbi->pseudo_pal; |
589 | 589 | ||
590 | ret = request_irq(irq, nuc900fb_irqhandler, 0, | 590 | ret = request_irq(irq, nuc900fb_irqhandler, 0, pdev->name, fbi); |
591 | pdev->name, fbinfo); | ||
592 | if (ret) { | 591 | if (ret) { |
593 | dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n", | 592 | dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n", |
594 | irq, ret); | 593 | irq, ret); |
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig index 56cad0f5386c..63b23f87081d 100644 --- a/drivers/video/omap2/Kconfig +++ b/drivers/video/omap2/Kconfig | |||
@@ -5,7 +5,6 @@ if ARCH_OMAP2PLUS | |||
5 | 5 | ||
6 | source "drivers/video/omap2/dss/Kconfig" | 6 | source "drivers/video/omap2/dss/Kconfig" |
7 | source "drivers/video/omap2/omapfb/Kconfig" | 7 | source "drivers/video/omap2/omapfb/Kconfig" |
8 | source "drivers/video/omap2/displays/Kconfig" | ||
9 | source "drivers/video/omap2/displays-new/Kconfig" | 8 | source "drivers/video/omap2/displays-new/Kconfig" |
10 | 9 | ||
11 | endif | 10 | endif |
diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile index 86873c2fbb27..bf8127df8c71 100644 --- a/drivers/video/omap2/Makefile +++ b/drivers/video/omap2/Makefile | |||
@@ -1,6 +1,5 @@ | |||
1 | obj-$(CONFIG_OMAP2_VRFB) += vrfb.o | 1 | obj-$(CONFIG_OMAP2_VRFB) += vrfb.o |
2 | 2 | ||
3 | obj-$(CONFIG_OMAP2_DSS) += dss/ | 3 | obj-$(CONFIG_OMAP2_DSS) += dss/ |
4 | obj-y += displays/ | ||
5 | obj-y += displays-new/ | 4 | obj-y += displays-new/ |
6 | obj-$(CONFIG_FB_OMAP2) += omapfb/ | 5 | obj-$(CONFIG_FB_OMAP2) += omapfb/ |
diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/omap2/displays-new/connector-analog-tv.c index 5338f362293b..1b60698f141e 100644 --- a/drivers/video/omap2/displays-new/connector-analog-tv.c +++ b/drivers/video/omap2/displays-new/connector-analog-tv.c | |||
@@ -28,6 +28,20 @@ struct panel_drv_data { | |||
28 | bool invert_polarity; | 28 | bool invert_polarity; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static const struct omap_video_timings tvc_pal_timings = { | ||
32 | .x_res = 720, | ||
33 | .y_res = 574, | ||
34 | .pixel_clock = 13500, | ||
35 | .hsw = 64, | ||
36 | .hfp = 12, | ||
37 | .hbp = 68, | ||
38 | .vsw = 5, | ||
39 | .vfp = 5, | ||
40 | .vbp = 41, | ||
41 | |||
42 | .interlace = true, | ||
43 | }; | ||
44 | |||
31 | #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) | 45 | #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) |
32 | 46 | ||
33 | static int tvc_connect(struct omap_dss_device *dssdev) | 47 | static int tvc_connect(struct omap_dss_device *dssdev) |
@@ -212,14 +226,14 @@ static int tvc_probe(struct platform_device *pdev) | |||
212 | return -ENODEV; | 226 | return -ENODEV; |
213 | } | 227 | } |
214 | 228 | ||
215 | ddata->timings = omap_dss_pal_timings; | 229 | ddata->timings = tvc_pal_timings; |
216 | 230 | ||
217 | dssdev = &ddata->dssdev; | 231 | dssdev = &ddata->dssdev; |
218 | dssdev->driver = &tvc_driver; | 232 | dssdev->driver = &tvc_driver; |
219 | dssdev->dev = &pdev->dev; | 233 | dssdev->dev = &pdev->dev; |
220 | dssdev->type = OMAP_DISPLAY_TYPE_VENC; | 234 | dssdev->type = OMAP_DISPLAY_TYPE_VENC; |
221 | dssdev->owner = THIS_MODULE; | 235 | dssdev->owner = THIS_MODULE; |
222 | dssdev->panel.timings = omap_dss_pal_timings; | 236 | dssdev->panel.timings = tvc_pal_timings; |
223 | 237 | ||
224 | r = omapdss_register_display(dssdev); | 238 | r = omapdss_register_display(dssdev); |
225 | if (r) { | 239 | if (r) { |
diff --git a/drivers/video/omap2/displays-new/encoder-tfp410.c b/drivers/video/omap2/displays-new/encoder-tfp410.c index a04f65856d6b..4a291e756be9 100644 --- a/drivers/video/omap2/displays-new/encoder-tfp410.c +++ b/drivers/video/omap2/displays-new/encoder-tfp410.c | |||
@@ -43,8 +43,8 @@ static int tfp410_connect(struct omap_dss_device *dssdev, | |||
43 | if (r) | 43 | if (r) |
44 | return r; | 44 | return r; |
45 | 45 | ||
46 | dst->output = dssdev; | 46 | dst->src = dssdev; |
47 | dssdev->device = dst; | 47 | dssdev->dst = dst; |
48 | 48 | ||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
@@ -59,12 +59,12 @@ static void tfp410_disconnect(struct omap_dss_device *dssdev, | |||
59 | if (!omapdss_device_is_connected(dssdev)) | 59 | if (!omapdss_device_is_connected(dssdev)) |
60 | return; | 60 | return; |
61 | 61 | ||
62 | WARN_ON(dst != dssdev->device); | 62 | WARN_ON(dst != dssdev->dst); |
63 | if (dst != dssdev->device) | 63 | if (dst != dssdev->dst) |
64 | return; | 64 | return; |
65 | 65 | ||
66 | dst->output = NULL; | 66 | dst->src = NULL; |
67 | dssdev->device = NULL; | 67 | dssdev->dst = NULL; |
68 | 68 | ||
69 | in->ops.dpi->disconnect(in, &ddata->dssdev); | 69 | in->ops.dpi->disconnect(in, &ddata->dssdev); |
70 | } | 70 | } |
@@ -244,7 +244,7 @@ static int __exit tfp410_remove(struct platform_device *pdev) | |||
244 | 244 | ||
245 | WARN_ON(omapdss_device_is_connected(dssdev)); | 245 | WARN_ON(omapdss_device_is_connected(dssdev)); |
246 | if (omapdss_device_is_connected(dssdev)) | 246 | if (omapdss_device_is_connected(dssdev)) |
247 | tfp410_disconnect(dssdev, dssdev->device); | 247 | tfp410_disconnect(dssdev, dssdev->dst); |
248 | 248 | ||
249 | omap_dss_put_device(in); | 249 | omap_dss_put_device(in); |
250 | 250 | ||
diff --git a/drivers/video/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/omap2/displays-new/encoder-tpd12s015.c index ce0e010026cb..798ef200b055 100644 --- a/drivers/video/omap2/displays-new/encoder-tpd12s015.c +++ b/drivers/video/omap2/displays-new/encoder-tpd12s015.c | |||
@@ -66,8 +66,8 @@ static int tpd_connect(struct omap_dss_device *dssdev, | |||
66 | if (r) | 66 | if (r) |
67 | return r; | 67 | return r; |
68 | 68 | ||
69 | dst->output = dssdev; | 69 | dst->src = dssdev; |
70 | dssdev->device = dst; | 70 | dssdev->dst = dst; |
71 | 71 | ||
72 | INIT_COMPLETION(ddata->hpd_completion); | 72 | INIT_COMPLETION(ddata->hpd_completion); |
73 | 73 | ||
@@ -95,15 +95,15 @@ static void tpd_disconnect(struct omap_dss_device *dssdev, | |||
95 | struct panel_drv_data *ddata = to_panel_data(dssdev); | 95 | struct panel_drv_data *ddata = to_panel_data(dssdev); |
96 | struct omap_dss_device *in = ddata->in; | 96 | struct omap_dss_device *in = ddata->in; |
97 | 97 | ||
98 | WARN_ON(dst != dssdev->device); | 98 | WARN_ON(dst != dssdev->dst); |
99 | 99 | ||
100 | if (dst != dssdev->device) | 100 | if (dst != dssdev->dst) |
101 | return; | 101 | return; |
102 | 102 | ||
103 | gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0); | 103 | gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0); |
104 | 104 | ||
105 | dst->output = NULL; | 105 | dst->src = NULL; |
106 | dssdev->device = NULL; | 106 | dssdev->dst = NULL; |
107 | 107 | ||
108 | in->ops.hdmi->disconnect(in, &ddata->dssdev); | 108 | in->ops.hdmi->disconnect(in, &ddata->dssdev); |
109 | } | 109 | } |
@@ -372,7 +372,7 @@ static int __exit tpd_remove(struct platform_device *pdev) | |||
372 | 372 | ||
373 | WARN_ON(omapdss_device_is_connected(dssdev)); | 373 | WARN_ON(omapdss_device_is_connected(dssdev)); |
374 | if (omapdss_device_is_connected(dssdev)) | 374 | if (omapdss_device_is_connected(dssdev)) |
375 | tpd_disconnect(dssdev, dssdev->device); | 375 | tpd_disconnect(dssdev, dssdev->dst); |
376 | 376 | ||
377 | omap_dss_put_device(in); | 377 | omap_dss_put_device(in); |
378 | 378 | ||
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig deleted file mode 100644 index e80ac1c79561..000000000000 --- a/drivers/video/omap2/displays/Kconfig +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | menu "OMAP2/3 Display Device Drivers (old device model)" | ||
2 | depends on OMAP2_DSS | ||
3 | |||
4 | config PANEL_GENERIC_DPI | ||
5 | tristate "Generic DPI Panel" | ||
6 | depends on OMAP2_DSS_DPI | ||
7 | help | ||
8 | Generic DPI panel driver. | ||
9 | Supports DVI output for Beagle and OMAP3 SDP. | ||
10 | Supports LCD Panel used in TI SDP3430 and EVM boards, | ||
11 | OMAP3517 EVM boards and CM-T35. | ||
12 | |||
13 | config PANEL_TFP410 | ||
14 | tristate "TFP410 DPI-to-DVI chip" | ||
15 | depends on OMAP2_DSS_DPI && I2C | ||
16 | help | ||
17 | Driver for TFP410 DPI-to-DVI chip. The driver uses i2c to read EDID | ||
18 | information from the monitor. | ||
19 | |||
20 | config PANEL_LGPHILIPS_LB035Q02 | ||
21 | tristate "LG.Philips LB035Q02 LCD Panel" | ||
22 | depends on OMAP2_DSS_DPI && SPI | ||
23 | help | ||
24 | LCD Panel used on the Gumstix Overo Palo35 | ||
25 | |||
26 | config PANEL_SHARP_LS037V7DW01 | ||
27 | tristate "Sharp LS037V7DW01 LCD Panel" | ||
28 | depends on OMAP2_DSS_DPI | ||
29 | depends on BACKLIGHT_CLASS_DEVICE | ||
30 | help | ||
31 | LCD Panel used in TI's SDP3430 and EVM boards | ||
32 | |||
33 | config PANEL_NEC_NL8048HL11_01B | ||
34 | tristate "NEC NL8048HL11-01B Panel" | ||
35 | depends on OMAP2_DSS_DPI | ||
36 | depends on SPI | ||
37 | depends on BACKLIGHT_CLASS_DEVICE | ||
38 | help | ||
39 | This NEC NL8048HL11-01B panel is TFT LCD | ||
40 | used in the Zoom2/3/3630 sdp boards. | ||
41 | |||
42 | config PANEL_PICODLP | ||
43 | tristate "TI PICO DLP mini-projector" | ||
44 | depends on OMAP2_DSS_DPI && I2C | ||
45 | help | ||
46 | A mini-projector used in TI's SDP4430 and EVM boards | ||
47 | For more info please visit http://www.dlp.com/projector/ | ||
48 | |||
49 | config PANEL_TAAL | ||
50 | tristate "Taal DSI Panel" | ||
51 | depends on OMAP2_DSS_DSI | ||
52 | depends on BACKLIGHT_CLASS_DEVICE | ||
53 | help | ||
54 | Taal DSI command mode panel from TPO. | ||
55 | |||
56 | config PANEL_TPO_TD043MTEA1 | ||
57 | tristate "TPO TD043MTEA1 LCD Panel" | ||
58 | depends on OMAP2_DSS_DPI && SPI | ||
59 | help | ||
60 | LCD Panel used in OMAP3 Pandora | ||
61 | |||
62 | config PANEL_ACX565AKM | ||
63 | tristate "ACX565AKM Panel" | ||
64 | depends on OMAP2_DSS_SDI && SPI | ||
65 | depends on BACKLIGHT_CLASS_DEVICE | ||
66 | help | ||
67 | This is the LCD panel used on Nokia N900 | ||
68 | |||
69 | config PANEL_N8X0 | ||
70 | tristate "N8X0 Panel" | ||
71 | depends on OMAP2_DSS_RFBI && SPI | ||
72 | depends on BACKLIGHT_CLASS_DEVICE | ||
73 | help | ||
74 | This is the LCD panel used on Nokia N8x0 | ||
75 | endmenu | ||
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile deleted file mode 100644 index 58a5176b07b0..000000000000 --- a/drivers/video/omap2/displays/Makefile +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o | ||
2 | obj-$(CONFIG_PANEL_TFP410) += panel-tfp410.o | ||
3 | obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o | ||
4 | obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o | ||
5 | obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o | ||
6 | |||
7 | obj-$(CONFIG_PANEL_TAAL) += panel-taal.o | ||
8 | obj-$(CONFIG_PANEL_PICODLP) += panel-picodlp.o | ||
9 | obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o | ||
10 | obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o | ||
11 | obj-$(CONFIG_PANEL_N8X0) += panel-n8x0.o | ||
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c deleted file mode 100644 index 3fd100fc853e..000000000000 --- a/drivers/video/omap2/displays/panel-acx565akm.c +++ /dev/null | |||
@@ -1,798 +0,0 @@ | |||
1 | /* | ||
2 | * Support for ACX565AKM LCD Panel used on Nokia N900 | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation | ||
5 | * | ||
6 | * Original Driver Author: Imre Deak <imre.deak@nokia.com> | ||
7 | * Based on panel-generic.c by Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
8 | * Adapted to new DSS2 framework: Roger Quadros <roger.quadros@nokia.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published by | ||
12 | * the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
17 | * more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along with | ||
20 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/backlight.h> | ||
31 | #include <linux/fb.h> | ||
32 | #include <linux/gpio.h> | ||
33 | |||
34 | #include <video/omapdss.h> | ||
35 | #include <video/omap-panel-data.h> | ||
36 | |||
37 | #define MIPID_CMD_READ_DISP_ID 0x04 | ||
38 | #define MIPID_CMD_READ_RED 0x06 | ||
39 | #define MIPID_CMD_READ_GREEN 0x07 | ||
40 | #define MIPID_CMD_READ_BLUE 0x08 | ||
41 | #define MIPID_CMD_READ_DISP_STATUS 0x09 | ||
42 | #define MIPID_CMD_RDDSDR 0x0F | ||
43 | #define MIPID_CMD_SLEEP_IN 0x10 | ||
44 | #define MIPID_CMD_SLEEP_OUT 0x11 | ||
45 | #define MIPID_CMD_DISP_OFF 0x28 | ||
46 | #define MIPID_CMD_DISP_ON 0x29 | ||
47 | #define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51 | ||
48 | #define MIPID_CMD_READ_DISP_BRIGHTNESS 0x52 | ||
49 | #define MIPID_CMD_WRITE_CTRL_DISP 0x53 | ||
50 | |||
51 | #define CTRL_DISP_BRIGHTNESS_CTRL_ON (1 << 5) | ||
52 | #define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4) | ||
53 | #define CTRL_DISP_BACKLIGHT_ON (1 << 2) | ||
54 | #define CTRL_DISP_AUTO_BRIGHTNESS_ON (1 << 1) | ||
55 | |||
56 | #define MIPID_CMD_READ_CTRL_DISP 0x54 | ||
57 | #define MIPID_CMD_WRITE_CABC 0x55 | ||
58 | #define MIPID_CMD_READ_CABC 0x56 | ||
59 | |||
60 | #define MIPID_VER_LPH8923 3 | ||
61 | #define MIPID_VER_LS041Y3 4 | ||
62 | #define MIPID_VER_L4F00311 8 | ||
63 | #define MIPID_VER_ACX565AKM 9 | ||
64 | |||
65 | struct acx565akm_device { | ||
66 | char *name; | ||
67 | int enabled; | ||
68 | int model; | ||
69 | int revision; | ||
70 | u8 display_id[3]; | ||
71 | unsigned has_bc:1; | ||
72 | unsigned has_cabc:1; | ||
73 | unsigned cabc_mode; | ||
74 | unsigned long hw_guard_end; /* next value of jiffies | ||
75 | when we can issue the | ||
76 | next sleep in/out command */ | ||
77 | unsigned long hw_guard_wait; /* max guard time in jiffies */ | ||
78 | |||
79 | struct spi_device *spi; | ||
80 | struct mutex mutex; | ||
81 | |||
82 | struct omap_dss_device *dssdev; | ||
83 | struct backlight_device *bl_dev; | ||
84 | }; | ||
85 | |||
86 | static struct acx565akm_device acx_dev; | ||
87 | static int acx565akm_bl_update_status(struct backlight_device *dev); | ||
88 | |||
89 | /*--------------------MIPID interface-----------------------------*/ | ||
90 | |||
91 | static void acx565akm_transfer(struct acx565akm_device *md, int cmd, | ||
92 | const u8 *wbuf, int wlen, u8 *rbuf, int rlen) | ||
93 | { | ||
94 | struct spi_message m; | ||
95 | struct spi_transfer *x, xfer[5]; | ||
96 | int r; | ||
97 | |||
98 | BUG_ON(md->spi == NULL); | ||
99 | |||
100 | spi_message_init(&m); | ||
101 | |||
102 | memset(xfer, 0, sizeof(xfer)); | ||
103 | x = &xfer[0]; | ||
104 | |||
105 | cmd &= 0xff; | ||
106 | x->tx_buf = &cmd; | ||
107 | x->bits_per_word = 9; | ||
108 | x->len = 2; | ||
109 | |||
110 | if (rlen > 1 && wlen == 0) { | ||
111 | /* | ||
112 | * Between the command and the response data there is a | ||
113 | * dummy clock cycle. Add an extra bit after the command | ||
114 | * word to account for this. | ||
115 | */ | ||
116 | x->bits_per_word = 10; | ||
117 | cmd <<= 1; | ||
118 | } | ||
119 | spi_message_add_tail(x, &m); | ||
120 | |||
121 | if (wlen) { | ||
122 | x++; | ||
123 | x->tx_buf = wbuf; | ||
124 | x->len = wlen; | ||
125 | x->bits_per_word = 9; | ||
126 | spi_message_add_tail(x, &m); | ||
127 | } | ||
128 | |||
129 | if (rlen) { | ||
130 | x++; | ||
131 | x->rx_buf = rbuf; | ||
132 | x->len = rlen; | ||
133 | spi_message_add_tail(x, &m); | ||
134 | } | ||
135 | |||
136 | r = spi_sync(md->spi, &m); | ||
137 | if (r < 0) | ||
138 | dev_dbg(&md->spi->dev, "spi_sync %d\n", r); | ||
139 | } | ||
140 | |||
141 | static inline void acx565akm_cmd(struct acx565akm_device *md, int cmd) | ||
142 | { | ||
143 | acx565akm_transfer(md, cmd, NULL, 0, NULL, 0); | ||
144 | } | ||
145 | |||
146 | static inline void acx565akm_write(struct acx565akm_device *md, | ||
147 | int reg, const u8 *buf, int len) | ||
148 | { | ||
149 | acx565akm_transfer(md, reg, buf, len, NULL, 0); | ||
150 | } | ||
151 | |||
152 | static inline void acx565akm_read(struct acx565akm_device *md, | ||
153 | int reg, u8 *buf, int len) | ||
154 | { | ||
155 | acx565akm_transfer(md, reg, NULL, 0, buf, len); | ||
156 | } | ||
157 | |||
158 | static void hw_guard_start(struct acx565akm_device *md, int guard_msec) | ||
159 | { | ||
160 | md->hw_guard_wait = msecs_to_jiffies(guard_msec); | ||
161 | md->hw_guard_end = jiffies + md->hw_guard_wait; | ||
162 | } | ||
163 | |||
164 | static void hw_guard_wait(struct acx565akm_device *md) | ||
165 | { | ||
166 | unsigned long wait = md->hw_guard_end - jiffies; | ||
167 | |||
168 | if ((long)wait > 0 && wait <= md->hw_guard_wait) { | ||
169 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
170 | schedule_timeout(wait); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /*----------------------MIPID wrappers----------------------------*/ | ||
175 | |||
176 | static void set_sleep_mode(struct acx565akm_device *md, int on) | ||
177 | { | ||
178 | int cmd; | ||
179 | |||
180 | if (on) | ||
181 | cmd = MIPID_CMD_SLEEP_IN; | ||
182 | else | ||
183 | cmd = MIPID_CMD_SLEEP_OUT; | ||
184 | /* | ||
185 | * We have to keep 120msec between sleep in/out commands. | ||
186 | * (8.2.15, 8.2.16). | ||
187 | */ | ||
188 | hw_guard_wait(md); | ||
189 | acx565akm_cmd(md, cmd); | ||
190 | hw_guard_start(md, 120); | ||
191 | } | ||
192 | |||
193 | static void set_display_state(struct acx565akm_device *md, int enabled) | ||
194 | { | ||
195 | int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; | ||
196 | |||
197 | acx565akm_cmd(md, cmd); | ||
198 | } | ||
199 | |||
200 | static int panel_enabled(struct acx565akm_device *md) | ||
201 | { | ||
202 | u32 disp_status; | ||
203 | int enabled; | ||
204 | |||
205 | acx565akm_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); | ||
206 | disp_status = __be32_to_cpu(disp_status); | ||
207 | enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); | ||
208 | dev_dbg(&md->spi->dev, | ||
209 | "LCD panel %senabled by bootloader (status 0x%04x)\n", | ||
210 | enabled ? "" : "not ", disp_status); | ||
211 | return enabled; | ||
212 | } | ||
213 | |||
214 | static int panel_detect(struct acx565akm_device *md) | ||
215 | { | ||
216 | acx565akm_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3); | ||
217 | dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", | ||
218 | md->display_id[0], md->display_id[1], md->display_id[2]); | ||
219 | |||
220 | switch (md->display_id[0]) { | ||
221 | case 0x10: | ||
222 | md->model = MIPID_VER_ACX565AKM; | ||
223 | md->name = "acx565akm"; | ||
224 | md->has_bc = 1; | ||
225 | md->has_cabc = 1; | ||
226 | break; | ||
227 | case 0x29: | ||
228 | md->model = MIPID_VER_L4F00311; | ||
229 | md->name = "l4f00311"; | ||
230 | break; | ||
231 | case 0x45: | ||
232 | md->model = MIPID_VER_LPH8923; | ||
233 | md->name = "lph8923"; | ||
234 | break; | ||
235 | case 0x83: | ||
236 | md->model = MIPID_VER_LS041Y3; | ||
237 | md->name = "ls041y3"; | ||
238 | break; | ||
239 | default: | ||
240 | md->name = "unknown"; | ||
241 | dev_err(&md->spi->dev, "invalid display ID\n"); | ||
242 | return -ENODEV; | ||
243 | } | ||
244 | |||
245 | md->revision = md->display_id[1]; | ||
246 | |||
247 | dev_info(&md->spi->dev, "omapfb: %s rev %02x LCD detected\n", | ||
248 | md->name, md->revision); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | /*----------------------Backlight Control-------------------------*/ | ||
254 | |||
255 | static void enable_backlight_ctrl(struct acx565akm_device *md, int enable) | ||
256 | { | ||
257 | u16 ctrl; | ||
258 | |||
259 | acx565akm_read(md, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1); | ||
260 | if (enable) { | ||
261 | ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON | | ||
262 | CTRL_DISP_BACKLIGHT_ON; | ||
263 | } else { | ||
264 | ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON | | ||
265 | CTRL_DISP_BACKLIGHT_ON); | ||
266 | } | ||
267 | |||
268 | ctrl |= 1 << 8; | ||
269 | acx565akm_write(md, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2); | ||
270 | } | ||
271 | |||
272 | static void set_cabc_mode(struct acx565akm_device *md, unsigned mode) | ||
273 | { | ||
274 | u16 cabc_ctrl; | ||
275 | |||
276 | md->cabc_mode = mode; | ||
277 | if (!md->enabled) | ||
278 | return; | ||
279 | cabc_ctrl = 0; | ||
280 | acx565akm_read(md, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1); | ||
281 | cabc_ctrl &= ~3; | ||
282 | cabc_ctrl |= (1 << 8) | (mode & 3); | ||
283 | acx565akm_write(md, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2); | ||
284 | } | ||
285 | |||
286 | static unsigned get_cabc_mode(struct acx565akm_device *md) | ||
287 | { | ||
288 | return md->cabc_mode; | ||
289 | } | ||
290 | |||
291 | static unsigned get_hw_cabc_mode(struct acx565akm_device *md) | ||
292 | { | ||
293 | u8 cabc_ctrl; | ||
294 | |||
295 | acx565akm_read(md, MIPID_CMD_READ_CABC, &cabc_ctrl, 1); | ||
296 | return cabc_ctrl & 3; | ||
297 | } | ||
298 | |||
299 | static void acx565akm_set_brightness(struct acx565akm_device *md, int level) | ||
300 | { | ||
301 | int bv; | ||
302 | |||
303 | bv = level | (1 << 8); | ||
304 | acx565akm_write(md, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2); | ||
305 | |||
306 | if (level) | ||
307 | enable_backlight_ctrl(md, 1); | ||
308 | else | ||
309 | enable_backlight_ctrl(md, 0); | ||
310 | } | ||
311 | |||
312 | static int acx565akm_get_actual_brightness(struct acx565akm_device *md) | ||
313 | { | ||
314 | u8 bv; | ||
315 | |||
316 | acx565akm_read(md, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1); | ||
317 | |||
318 | return bv; | ||
319 | } | ||
320 | |||
321 | |||
322 | static int acx565akm_bl_update_status(struct backlight_device *dev) | ||
323 | { | ||
324 | struct acx565akm_device *md = dev_get_drvdata(&dev->dev); | ||
325 | int r; | ||
326 | int level; | ||
327 | |||
328 | dev_dbg(&md->spi->dev, "%s\n", __func__); | ||
329 | |||
330 | mutex_lock(&md->mutex); | ||
331 | |||
332 | if (dev->props.fb_blank == FB_BLANK_UNBLANK && | ||
333 | dev->props.power == FB_BLANK_UNBLANK) | ||
334 | level = dev->props.brightness; | ||
335 | else | ||
336 | level = 0; | ||
337 | |||
338 | r = 0; | ||
339 | if (md->has_bc) | ||
340 | acx565akm_set_brightness(md, level); | ||
341 | else | ||
342 | r = -ENODEV; | ||
343 | |||
344 | mutex_unlock(&md->mutex); | ||
345 | |||
346 | return r; | ||
347 | } | ||
348 | |||
349 | static int acx565akm_bl_get_intensity(struct backlight_device *dev) | ||
350 | { | ||
351 | struct acx565akm_device *md = dev_get_drvdata(&dev->dev); | ||
352 | |||
353 | dev_dbg(&dev->dev, "%s\n", __func__); | ||
354 | |||
355 | if (!md->has_bc) | ||
356 | return -ENODEV; | ||
357 | |||
358 | if (dev->props.fb_blank == FB_BLANK_UNBLANK && | ||
359 | dev->props.power == FB_BLANK_UNBLANK) { | ||
360 | if (md->has_bc) | ||
361 | return acx565akm_get_actual_brightness(md); | ||
362 | else | ||
363 | return dev->props.brightness; | ||
364 | } | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | static const struct backlight_ops acx565akm_bl_ops = { | ||
370 | .get_brightness = acx565akm_bl_get_intensity, | ||
371 | .update_status = acx565akm_bl_update_status, | ||
372 | }; | ||
373 | |||
374 | /*--------------------Auto Brightness control via Sysfs---------------------*/ | ||
375 | |||
376 | static const char *cabc_modes[] = { | ||
377 | "off", /* always used when CABC is not supported */ | ||
378 | "ui", | ||
379 | "still-image", | ||
380 | "moving-image", | ||
381 | }; | ||
382 | |||
383 | static ssize_t show_cabc_mode(struct device *dev, | ||
384 | struct device_attribute *attr, | ||
385 | char *buf) | ||
386 | { | ||
387 | struct acx565akm_device *md = dev_get_drvdata(dev); | ||
388 | const char *mode_str; | ||
389 | int mode; | ||
390 | int len; | ||
391 | |||
392 | if (!md->has_cabc) | ||
393 | mode = 0; | ||
394 | else | ||
395 | mode = get_cabc_mode(md); | ||
396 | mode_str = "unknown"; | ||
397 | if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes)) | ||
398 | mode_str = cabc_modes[mode]; | ||
399 | len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str); | ||
400 | |||
401 | return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1; | ||
402 | } | ||
403 | |||
404 | static ssize_t store_cabc_mode(struct device *dev, | ||
405 | struct device_attribute *attr, | ||
406 | const char *buf, size_t count) | ||
407 | { | ||
408 | struct acx565akm_device *md = dev_get_drvdata(dev); | ||
409 | int i; | ||
410 | |||
411 | for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { | ||
412 | const char *mode_str = cabc_modes[i]; | ||
413 | int cmp_len = strlen(mode_str); | ||
414 | |||
415 | if (count > 0 && buf[count - 1] == '\n') | ||
416 | count--; | ||
417 | if (count != cmp_len) | ||
418 | continue; | ||
419 | |||
420 | if (strncmp(buf, mode_str, cmp_len) == 0) | ||
421 | break; | ||
422 | } | ||
423 | |||
424 | if (i == ARRAY_SIZE(cabc_modes)) | ||
425 | return -EINVAL; | ||
426 | |||
427 | if (!md->has_cabc && i != 0) | ||
428 | return -EINVAL; | ||
429 | |||
430 | mutex_lock(&md->mutex); | ||
431 | set_cabc_mode(md, i); | ||
432 | mutex_unlock(&md->mutex); | ||
433 | |||
434 | return count; | ||
435 | } | ||
436 | |||
437 | static ssize_t show_cabc_available_modes(struct device *dev, | ||
438 | struct device_attribute *attr, | ||
439 | char *buf) | ||
440 | { | ||
441 | struct acx565akm_device *md = dev_get_drvdata(dev); | ||
442 | int len; | ||
443 | int i; | ||
444 | |||
445 | if (!md->has_cabc) | ||
446 | return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]); | ||
447 | |||
448 | for (i = 0, len = 0; | ||
449 | len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++) | ||
450 | len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s", | ||
451 | i ? " " : "", cabc_modes[i], | ||
452 | i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : ""); | ||
453 | |||
454 | return len < PAGE_SIZE ? len : PAGE_SIZE - 1; | ||
455 | } | ||
456 | |||
457 | static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, | ||
458 | show_cabc_mode, store_cabc_mode); | ||
459 | static DEVICE_ATTR(cabc_available_modes, S_IRUGO, | ||
460 | show_cabc_available_modes, NULL); | ||
461 | |||
462 | static struct attribute *bldev_attrs[] = { | ||
463 | &dev_attr_cabc_mode.attr, | ||
464 | &dev_attr_cabc_available_modes.attr, | ||
465 | NULL, | ||
466 | }; | ||
467 | |||
468 | static struct attribute_group bldev_attr_group = { | ||
469 | .attrs = bldev_attrs, | ||
470 | }; | ||
471 | |||
472 | |||
473 | /*---------------------------ACX Panel----------------------------*/ | ||
474 | |||
475 | static int acx_get_recommended_bpp(struct omap_dss_device *dssdev) | ||
476 | { | ||
477 | return 16; | ||
478 | } | ||
479 | |||
480 | static struct omap_video_timings acx_panel_timings = { | ||
481 | .x_res = 800, | ||
482 | .y_res = 480, | ||
483 | .pixel_clock = 24000, | ||
484 | .hfp = 28, | ||
485 | .hsw = 4, | ||
486 | .hbp = 24, | ||
487 | .vfp = 3, | ||
488 | .vsw = 3, | ||
489 | .vbp = 4, | ||
490 | |||
491 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
492 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
493 | |||
494 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
495 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
496 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
497 | }; | ||
498 | |||
499 | static struct panel_acx565akm_data *get_panel_data(struct omap_dss_device *dssdev) | ||
500 | { | ||
501 | return (struct panel_acx565akm_data *) dssdev->data; | ||
502 | } | ||
503 | |||
504 | static int acx_panel_probe(struct omap_dss_device *dssdev) | ||
505 | { | ||
506 | int r; | ||
507 | struct acx565akm_device *md = &acx_dev; | ||
508 | struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); | ||
509 | struct backlight_device *bldev; | ||
510 | int max_brightness, brightness; | ||
511 | struct backlight_properties props; | ||
512 | |||
513 | dev_dbg(dssdev->dev, "%s\n", __func__); | ||
514 | |||
515 | if (!panel_data) | ||
516 | return -EINVAL; | ||
517 | |||
518 | /* FIXME AC bias ? */ | ||
519 | dssdev->panel.timings = acx_panel_timings; | ||
520 | |||
521 | if (gpio_is_valid(panel_data->reset_gpio)) { | ||
522 | r = devm_gpio_request_one(dssdev->dev, panel_data->reset_gpio, | ||
523 | GPIOF_OUT_INIT_LOW, "lcd reset"); | ||
524 | if (r) | ||
525 | return r; | ||
526 | } | ||
527 | |||
528 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
529 | gpio_set_value(panel_data->reset_gpio, 1); | ||
530 | |||
531 | /* | ||
532 | * After reset we have to wait 5 msec before the first | ||
533 | * command can be sent. | ||
534 | */ | ||
535 | msleep(5); | ||
536 | |||
537 | md->enabled = panel_enabled(md); | ||
538 | |||
539 | r = panel_detect(md); | ||
540 | if (r) { | ||
541 | dev_err(dssdev->dev, "%s panel detect error\n", __func__); | ||
542 | if (!md->enabled && gpio_is_valid(panel_data->reset_gpio)) | ||
543 | gpio_set_value(panel_data->reset_gpio, 0); | ||
544 | |||
545 | return r; | ||
546 | } | ||
547 | |||
548 | mutex_lock(&acx_dev.mutex); | ||
549 | acx_dev.dssdev = dssdev; | ||
550 | mutex_unlock(&acx_dev.mutex); | ||
551 | |||
552 | if (!md->enabled) { | ||
553 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
554 | gpio_set_value(panel_data->reset_gpio, 0); | ||
555 | } | ||
556 | |||
557 | /*------- Backlight control --------*/ | ||
558 | |||
559 | memset(&props, 0, sizeof(props)); | ||
560 | props.fb_blank = FB_BLANK_UNBLANK; | ||
561 | props.power = FB_BLANK_UNBLANK; | ||
562 | props.type = BACKLIGHT_RAW; | ||
563 | |||
564 | bldev = backlight_device_register("acx565akm", &md->spi->dev, | ||
565 | md, &acx565akm_bl_ops, &props); | ||
566 | md->bl_dev = bldev; | ||
567 | if (md->has_cabc) { | ||
568 | r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); | ||
569 | if (r) { | ||
570 | dev_err(&bldev->dev, | ||
571 | "%s failed to create sysfs files\n", __func__); | ||
572 | backlight_device_unregister(bldev); | ||
573 | return r; | ||
574 | } | ||
575 | md->cabc_mode = get_hw_cabc_mode(md); | ||
576 | } | ||
577 | |||
578 | max_brightness = 255; | ||
579 | |||
580 | if (md->has_bc) | ||
581 | brightness = acx565akm_get_actual_brightness(md); | ||
582 | else | ||
583 | brightness = 0; | ||
584 | |||
585 | bldev->props.max_brightness = max_brightness; | ||
586 | bldev->props.brightness = brightness; | ||
587 | |||
588 | acx565akm_bl_update_status(bldev); | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | static void acx_panel_remove(struct omap_dss_device *dssdev) | ||
593 | { | ||
594 | struct acx565akm_device *md = &acx_dev; | ||
595 | |||
596 | dev_dbg(dssdev->dev, "%s\n", __func__); | ||
597 | sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group); | ||
598 | backlight_device_unregister(md->bl_dev); | ||
599 | mutex_lock(&acx_dev.mutex); | ||
600 | acx_dev.dssdev = NULL; | ||
601 | mutex_unlock(&acx_dev.mutex); | ||
602 | } | ||
603 | |||
604 | static int acx_panel_power_on(struct omap_dss_device *dssdev) | ||
605 | { | ||
606 | struct acx565akm_device *md = &acx_dev; | ||
607 | struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); | ||
608 | int r; | ||
609 | |||
610 | dev_dbg(dssdev->dev, "%s\n", __func__); | ||
611 | |||
612 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
613 | return 0; | ||
614 | |||
615 | mutex_lock(&md->mutex); | ||
616 | |||
617 | omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings); | ||
618 | omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs); | ||
619 | |||
620 | r = omapdss_sdi_display_enable(dssdev); | ||
621 | if (r) { | ||
622 | pr_err("%s sdi enable failed\n", __func__); | ||
623 | goto fail_unlock; | ||
624 | } | ||
625 | |||
626 | /*FIXME tweak me */ | ||
627 | msleep(50); | ||
628 | |||
629 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
630 | gpio_set_value(panel_data->reset_gpio, 1); | ||
631 | |||
632 | if (md->enabled) { | ||
633 | dev_dbg(&md->spi->dev, "panel already enabled\n"); | ||
634 | mutex_unlock(&md->mutex); | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | /* | ||
639 | * We have to meet all the following delay requirements: | ||
640 | * 1. tRW: reset pulse width 10usec (7.12.1) | ||
641 | * 2. tRT: reset cancel time 5msec (7.12.1) | ||
642 | * 3. Providing PCLK,HS,VS signals for 2 frames = ~50msec worst | ||
643 | * case (7.6.2) | ||
644 | * 4. 120msec before the sleep out command (7.12.1) | ||
645 | */ | ||
646 | msleep(120); | ||
647 | |||
648 | set_sleep_mode(md, 0); | ||
649 | md->enabled = 1; | ||
650 | |||
651 | /* 5msec between sleep out and the next command. (8.2.16) */ | ||
652 | msleep(5); | ||
653 | set_display_state(md, 1); | ||
654 | set_cabc_mode(md, md->cabc_mode); | ||
655 | |||
656 | mutex_unlock(&md->mutex); | ||
657 | |||
658 | return acx565akm_bl_update_status(md->bl_dev); | ||
659 | |||
660 | fail_unlock: | ||
661 | mutex_unlock(&md->mutex); | ||
662 | return r; | ||
663 | } | ||
664 | |||
665 | static void acx_panel_power_off(struct omap_dss_device *dssdev) | ||
666 | { | ||
667 | struct acx565akm_device *md = &acx_dev; | ||
668 | struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); | ||
669 | |||
670 | dev_dbg(dssdev->dev, "%s\n", __func__); | ||
671 | |||
672 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
673 | return; | ||
674 | |||
675 | mutex_lock(&md->mutex); | ||
676 | |||
677 | if (!md->enabled) { | ||
678 | mutex_unlock(&md->mutex); | ||
679 | return; | ||
680 | } | ||
681 | set_display_state(md, 0); | ||
682 | set_sleep_mode(md, 1); | ||
683 | md->enabled = 0; | ||
684 | /* | ||
685 | * We have to provide PCLK,HS,VS signals for 2 frames (worst case | ||
686 | * ~50msec) after sending the sleep in command and asserting the | ||
687 | * reset signal. We probably could assert the reset w/o the delay | ||
688 | * but we still delay to avoid possible artifacts. (7.6.1) | ||
689 | */ | ||
690 | msleep(50); | ||
691 | |||
692 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
693 | gpio_set_value(panel_data->reset_gpio, 0); | ||
694 | |||
695 | /* FIXME need to tweak this delay */ | ||
696 | msleep(100); | ||
697 | |||
698 | omapdss_sdi_display_disable(dssdev); | ||
699 | |||
700 | mutex_unlock(&md->mutex); | ||
701 | } | ||
702 | |||
703 | static int acx_panel_enable(struct omap_dss_device *dssdev) | ||
704 | { | ||
705 | int r; | ||
706 | |||
707 | dev_dbg(dssdev->dev, "%s\n", __func__); | ||
708 | r = acx_panel_power_on(dssdev); | ||
709 | |||
710 | if (r) | ||
711 | return r; | ||
712 | |||
713 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | static void acx_panel_disable(struct omap_dss_device *dssdev) | ||
718 | { | ||
719 | dev_dbg(dssdev->dev, "%s\n", __func__); | ||
720 | acx_panel_power_off(dssdev); | ||
721 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
722 | } | ||
723 | |||
724 | static void acx_panel_set_timings(struct omap_dss_device *dssdev, | ||
725 | struct omap_video_timings *timings) | ||
726 | { | ||
727 | omapdss_sdi_set_timings(dssdev, timings); | ||
728 | |||
729 | dssdev->panel.timings = *timings; | ||
730 | } | ||
731 | |||
732 | static int acx_panel_check_timings(struct omap_dss_device *dssdev, | ||
733 | struct omap_video_timings *timings) | ||
734 | { | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | |||
739 | static struct omap_dss_driver acx_panel_driver = { | ||
740 | .probe = acx_panel_probe, | ||
741 | .remove = acx_panel_remove, | ||
742 | |||
743 | .enable = acx_panel_enable, | ||
744 | .disable = acx_panel_disable, | ||
745 | |||
746 | .set_timings = acx_panel_set_timings, | ||
747 | .check_timings = acx_panel_check_timings, | ||
748 | |||
749 | .get_recommended_bpp = acx_get_recommended_bpp, | ||
750 | |||
751 | .driver = { | ||
752 | .name = "panel-acx565akm", | ||
753 | .owner = THIS_MODULE, | ||
754 | }, | ||
755 | }; | ||
756 | |||
757 | /*--------------------SPI probe-------------------------*/ | ||
758 | |||
759 | static int acx565akm_spi_probe(struct spi_device *spi) | ||
760 | { | ||
761 | struct acx565akm_device *md = &acx_dev; | ||
762 | |||
763 | dev_dbg(&spi->dev, "%s\n", __func__); | ||
764 | |||
765 | spi->mode = SPI_MODE_3; | ||
766 | md->spi = spi; | ||
767 | mutex_init(&md->mutex); | ||
768 | dev_set_drvdata(&spi->dev, md); | ||
769 | |||
770 | omap_dss_register_driver(&acx_panel_driver); | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static int acx565akm_spi_remove(struct spi_device *spi) | ||
776 | { | ||
777 | struct acx565akm_device *md = dev_get_drvdata(&spi->dev); | ||
778 | |||
779 | dev_dbg(&md->spi->dev, "%s\n", __func__); | ||
780 | omap_dss_unregister_driver(&acx_panel_driver); | ||
781 | |||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static struct spi_driver acx565akm_spi_driver = { | ||
786 | .driver = { | ||
787 | .name = "acx565akm", | ||
788 | .owner = THIS_MODULE, | ||
789 | }, | ||
790 | .probe = acx565akm_spi_probe, | ||
791 | .remove = acx565akm_spi_remove, | ||
792 | }; | ||
793 | |||
794 | module_spi_driver(acx565akm_spi_driver); | ||
795 | |||
796 | MODULE_AUTHOR("Nokia Corporation"); | ||
797 | MODULE_DESCRIPTION("acx565akm LCD Driver"); | ||
798 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c deleted file mode 100644 index bebebd45847f..000000000000 --- a/drivers/video/omap2/displays/panel-generic-dpi.c +++ /dev/null | |||
@@ -1,744 +0,0 @@ | |||
1 | /* | ||
2 | * Generic DPI Panels support | ||
3 | * | ||
4 | * Copyright (C) 2010 Canonical Ltd. | ||
5 | * Author: Bryan Wu <bryan.wu@canonical.com> | ||
6 | * | ||
7 | * LCD panel driver for Sharp LQ043T1DG01 | ||
8 | * | ||
9 | * Copyright (C) 2009 Texas Instruments Inc | ||
10 | * Author: Vaibhav Hiremath <hvaibhav@ti.com> | ||
11 | * | ||
12 | * LCD panel driver for Toppoly TDO35S | ||
13 | * | ||
14 | * Copyright (C) 2009 CompuLab, Ltd. | ||
15 | * Author: Mike Rapoport <mike@compulab.co.il> | ||
16 | * | ||
17 | * Copyright (C) 2008 Nokia Corporation | ||
18 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
19 | * | ||
20 | * This program is free software; you can redistribute it and/or modify it | ||
21 | * under the terms of the GNU General Public License version 2 as published by | ||
22 | * the Free Software Foundation. | ||
23 | * | ||
24 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
25 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
26 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
27 | * more details. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License along with | ||
30 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/gpio.h> | ||
37 | #include <video/omapdss.h> | ||
38 | |||
39 | #include <video/omap-panel-data.h> | ||
40 | |||
41 | struct panel_config { | ||
42 | struct omap_video_timings timings; | ||
43 | |||
44 | int power_on_delay; | ||
45 | int power_off_delay; | ||
46 | |||
47 | /* | ||
48 | * Used to match device to panel configuration | ||
49 | * when use generic panel driver | ||
50 | */ | ||
51 | const char *name; | ||
52 | }; | ||
53 | |||
54 | /* Panel configurations */ | ||
55 | static struct panel_config generic_dpi_panels[] = { | ||
56 | /* Sharp LQ043T1DG01 */ | ||
57 | { | ||
58 | { | ||
59 | .x_res = 480, | ||
60 | .y_res = 272, | ||
61 | |||
62 | .pixel_clock = 9000, | ||
63 | |||
64 | .hsw = 42, | ||
65 | .hfp = 3, | ||
66 | .hbp = 2, | ||
67 | |||
68 | .vsw = 11, | ||
69 | .vfp = 3, | ||
70 | .vbp = 2, | ||
71 | |||
72 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
73 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
74 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
75 | .de_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
76 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
77 | }, | ||
78 | .power_on_delay = 50, | ||
79 | .power_off_delay = 100, | ||
80 | .name = "sharp_lq", | ||
81 | }, | ||
82 | |||
83 | /* Sharp LS037V7DW01 */ | ||
84 | { | ||
85 | { | ||
86 | .x_res = 480, | ||
87 | .y_res = 640, | ||
88 | |||
89 | .pixel_clock = 19200, | ||
90 | |||
91 | .hsw = 2, | ||
92 | .hfp = 1, | ||
93 | .hbp = 28, | ||
94 | |||
95 | .vsw = 1, | ||
96 | .vfp = 1, | ||
97 | .vbp = 1, | ||
98 | |||
99 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
100 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
101 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
102 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
103 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
104 | }, | ||
105 | .power_on_delay = 50, | ||
106 | .power_off_delay = 100, | ||
107 | .name = "sharp_ls", | ||
108 | }, | ||
109 | |||
110 | /* Toppoly TDO35S */ | ||
111 | { | ||
112 | { | ||
113 | .x_res = 480, | ||
114 | .y_res = 640, | ||
115 | |||
116 | .pixel_clock = 26000, | ||
117 | |||
118 | .hfp = 104, | ||
119 | .hsw = 8, | ||
120 | .hbp = 8, | ||
121 | |||
122 | .vfp = 4, | ||
123 | .vsw = 2, | ||
124 | .vbp = 2, | ||
125 | |||
126 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
127 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
128 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
129 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
130 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
131 | }, | ||
132 | .power_on_delay = 0, | ||
133 | .power_off_delay = 0, | ||
134 | .name = "toppoly_tdo35s", | ||
135 | }, | ||
136 | |||
137 | /* Samsung LTE430WQ-F0C */ | ||
138 | { | ||
139 | { | ||
140 | .x_res = 480, | ||
141 | .y_res = 272, | ||
142 | |||
143 | .pixel_clock = 9200, | ||
144 | |||
145 | .hfp = 8, | ||
146 | .hsw = 41, | ||
147 | .hbp = 45 - 41, | ||
148 | |||
149 | .vfp = 4, | ||
150 | .vsw = 10, | ||
151 | .vbp = 12 - 10, | ||
152 | |||
153 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
154 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
155 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
156 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
157 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
158 | }, | ||
159 | .power_on_delay = 0, | ||
160 | .power_off_delay = 0, | ||
161 | .name = "samsung_lte430wq_f0c", | ||
162 | }, | ||
163 | |||
164 | /* Seiko 70WVW1TZ3Z3 */ | ||
165 | { | ||
166 | { | ||
167 | .x_res = 800, | ||
168 | .y_res = 480, | ||
169 | |||
170 | .pixel_clock = 33000, | ||
171 | |||
172 | .hsw = 128, | ||
173 | .hfp = 10, | ||
174 | .hbp = 10, | ||
175 | |||
176 | .vsw = 2, | ||
177 | .vfp = 4, | ||
178 | .vbp = 11, | ||
179 | |||
180 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
181 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
182 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
183 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
184 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
185 | }, | ||
186 | .power_on_delay = 0, | ||
187 | .power_off_delay = 0, | ||
188 | .name = "seiko_70wvw1tz3", | ||
189 | }, | ||
190 | |||
191 | /* Powertip PH480272T */ | ||
192 | { | ||
193 | { | ||
194 | .x_res = 480, | ||
195 | .y_res = 272, | ||
196 | |||
197 | .pixel_clock = 9000, | ||
198 | |||
199 | .hsw = 40, | ||
200 | .hfp = 2, | ||
201 | .hbp = 2, | ||
202 | |||
203 | .vsw = 10, | ||
204 | .vfp = 2, | ||
205 | .vbp = 2, | ||
206 | |||
207 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
208 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
209 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
210 | .de_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
211 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
212 | }, | ||
213 | .power_on_delay = 0, | ||
214 | .power_off_delay = 0, | ||
215 | .name = "powertip_ph480272t", | ||
216 | }, | ||
217 | |||
218 | /* Innolux AT070TN83 */ | ||
219 | { | ||
220 | { | ||
221 | .x_res = 800, | ||
222 | .y_res = 480, | ||
223 | |||
224 | .pixel_clock = 40000, | ||
225 | |||
226 | .hsw = 48, | ||
227 | .hfp = 1, | ||
228 | .hbp = 1, | ||
229 | |||
230 | .vsw = 3, | ||
231 | .vfp = 12, | ||
232 | .vbp = 25, | ||
233 | |||
234 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
235 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
236 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
237 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
238 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
239 | }, | ||
240 | .power_on_delay = 0, | ||
241 | .power_off_delay = 0, | ||
242 | .name = "innolux_at070tn83", | ||
243 | }, | ||
244 | |||
245 | /* NEC NL2432DR22-11B */ | ||
246 | { | ||
247 | { | ||
248 | .x_res = 240, | ||
249 | .y_res = 320, | ||
250 | |||
251 | .pixel_clock = 5400, | ||
252 | |||
253 | .hsw = 3, | ||
254 | .hfp = 3, | ||
255 | .hbp = 39, | ||
256 | |||
257 | .vsw = 1, | ||
258 | .vfp = 2, | ||
259 | .vbp = 7, | ||
260 | |||
261 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
262 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
263 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
264 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
265 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
266 | }, | ||
267 | .name = "nec_nl2432dr22-11b", | ||
268 | }, | ||
269 | |||
270 | /* Unknown panel used in OMAP H4 */ | ||
271 | { | ||
272 | { | ||
273 | .x_res = 240, | ||
274 | .y_res = 320, | ||
275 | |||
276 | .pixel_clock = 6250, | ||
277 | |||
278 | .hsw = 15, | ||
279 | .hfp = 15, | ||
280 | .hbp = 60, | ||
281 | |||
282 | .vsw = 1, | ||
283 | .vfp = 1, | ||
284 | .vbp = 1, | ||
285 | |||
286 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
287 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
288 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
289 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
290 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
291 | }, | ||
292 | .name = "h4", | ||
293 | }, | ||
294 | |||
295 | /* FocalTech ETM070003DH6 */ | ||
296 | { | ||
297 | { | ||
298 | .x_res = 800, | ||
299 | .y_res = 480, | ||
300 | |||
301 | .pixel_clock = 28000, | ||
302 | |||
303 | .hsw = 48, | ||
304 | .hfp = 40, | ||
305 | .hbp = 40, | ||
306 | |||
307 | .vsw = 3, | ||
308 | .vfp = 13, | ||
309 | .vbp = 29, | ||
310 | |||
311 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
312 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
313 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
314 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
315 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
316 | }, | ||
317 | .name = "focaltech_etm070003dh6", | ||
318 | }, | ||
319 | |||
320 | /* Microtips Technologies - UMSH-8173MD */ | ||
321 | { | ||
322 | { | ||
323 | .x_res = 800, | ||
324 | .y_res = 480, | ||
325 | |||
326 | .pixel_clock = 34560, | ||
327 | |||
328 | .hsw = 13, | ||
329 | .hfp = 101, | ||
330 | .hbp = 101, | ||
331 | |||
332 | .vsw = 23, | ||
333 | .vfp = 1, | ||
334 | .vbp = 1, | ||
335 | |||
336 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
337 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
338 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
339 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
340 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
341 | }, | ||
342 | .power_on_delay = 0, | ||
343 | .power_off_delay = 0, | ||
344 | .name = "microtips_umsh_8173md", | ||
345 | }, | ||
346 | |||
347 | /* OrtusTech COM43H4M10XTC */ | ||
348 | { | ||
349 | { | ||
350 | .x_res = 480, | ||
351 | .y_res = 272, | ||
352 | |||
353 | .pixel_clock = 8000, | ||
354 | |||
355 | .hsw = 41, | ||
356 | .hfp = 8, | ||
357 | .hbp = 4, | ||
358 | |||
359 | .vsw = 10, | ||
360 | .vfp = 4, | ||
361 | .vbp = 2, | ||
362 | |||
363 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
364 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
365 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
366 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
367 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
368 | }, | ||
369 | .name = "ortustech_com43h4m10xtc", | ||
370 | }, | ||
371 | |||
372 | /* Innolux AT080TN52 */ | ||
373 | { | ||
374 | { | ||
375 | .x_res = 800, | ||
376 | .y_res = 600, | ||
377 | |||
378 | .pixel_clock = 41142, | ||
379 | |||
380 | .hsw = 20, | ||
381 | .hfp = 210, | ||
382 | .hbp = 46, | ||
383 | |||
384 | .vsw = 10, | ||
385 | .vfp = 12, | ||
386 | .vbp = 23, | ||
387 | |||
388 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
389 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
390 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
391 | .de_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
392 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
393 | }, | ||
394 | .name = "innolux_at080tn52", | ||
395 | }, | ||
396 | |||
397 | /* Mitsubishi AA084SB01 */ | ||
398 | { | ||
399 | { | ||
400 | .x_res = 800, | ||
401 | .y_res = 600, | ||
402 | .pixel_clock = 40000, | ||
403 | |||
404 | .hsw = 1, | ||
405 | .hfp = 254, | ||
406 | .hbp = 1, | ||
407 | |||
408 | .vsw = 1, | ||
409 | .vfp = 26, | ||
410 | .vbp = 1, | ||
411 | |||
412 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
413 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
414 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
415 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
416 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
417 | }, | ||
418 | .name = "mitsubishi_aa084sb01", | ||
419 | }, | ||
420 | /* EDT ET0500G0DH6 */ | ||
421 | { | ||
422 | { | ||
423 | .x_res = 800, | ||
424 | .y_res = 480, | ||
425 | .pixel_clock = 33260, | ||
426 | |||
427 | .hsw = 128, | ||
428 | .hfp = 216, | ||
429 | .hbp = 40, | ||
430 | |||
431 | .vsw = 2, | ||
432 | .vfp = 35, | ||
433 | .vbp = 10, | ||
434 | |||
435 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
436 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
437 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
438 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
439 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
440 | }, | ||
441 | .name = "edt_et0500g0dh6", | ||
442 | }, | ||
443 | |||
444 | /* Prime-View PD050VL1 */ | ||
445 | { | ||
446 | { | ||
447 | .x_res = 640, | ||
448 | .y_res = 480, | ||
449 | |||
450 | .pixel_clock = 25000, | ||
451 | |||
452 | .hsw = 96, | ||
453 | .hfp = 18, | ||
454 | .hbp = 46, | ||
455 | |||
456 | .vsw = 2, | ||
457 | .vfp = 10, | ||
458 | .vbp = 33, | ||
459 | |||
460 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
461 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
462 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
463 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
464 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
465 | }, | ||
466 | .name = "primeview_pd050vl1", | ||
467 | }, | ||
468 | |||
469 | /* Prime-View PM070WL4 */ | ||
470 | { | ||
471 | { | ||
472 | .x_res = 800, | ||
473 | .y_res = 480, | ||
474 | |||
475 | .pixel_clock = 32000, | ||
476 | |||
477 | .hsw = 128, | ||
478 | .hfp = 42, | ||
479 | .hbp = 86, | ||
480 | |||
481 | .vsw = 2, | ||
482 | .vfp = 10, | ||
483 | .vbp = 33, | ||
484 | |||
485 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
486 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
487 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
488 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
489 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
490 | }, | ||
491 | .name = "primeview_pm070wl4", | ||
492 | }, | ||
493 | |||
494 | /* Prime-View PD104SLF */ | ||
495 | { | ||
496 | { | ||
497 | .x_res = 800, | ||
498 | .y_res = 600, | ||
499 | |||
500 | .pixel_clock = 40000, | ||
501 | |||
502 | .hsw = 128, | ||
503 | .hfp = 42, | ||
504 | .hbp = 86, | ||
505 | |||
506 | .vsw = 4, | ||
507 | .vfp = 1, | ||
508 | .vbp = 23, | ||
509 | |||
510 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
511 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
512 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
513 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
514 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
515 | }, | ||
516 | .name = "primeview_pd104slf", | ||
517 | }, | ||
518 | }; | ||
519 | |||
520 | struct panel_drv_data { | ||
521 | |||
522 | struct omap_dss_device *dssdev; | ||
523 | |||
524 | struct panel_config *panel_config; | ||
525 | |||
526 | struct mutex lock; | ||
527 | }; | ||
528 | |||
529 | static inline struct panel_generic_dpi_data | ||
530 | *get_panel_data(const struct omap_dss_device *dssdev) | ||
531 | { | ||
532 | return (struct panel_generic_dpi_data *) dssdev->data; | ||
533 | } | ||
534 | |||
535 | static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev) | ||
536 | { | ||
537 | int r, i; | ||
538 | struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); | ||
539 | struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); | ||
540 | struct panel_config *panel_config = drv_data->panel_config; | ||
541 | |||
542 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
543 | return 0; | ||
544 | |||
545 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
546 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
547 | |||
548 | r = omapdss_dpi_display_enable(dssdev); | ||
549 | if (r) | ||
550 | goto err0; | ||
551 | |||
552 | /* wait couple of vsyncs until enabling the LCD */ | ||
553 | if (panel_config->power_on_delay) | ||
554 | msleep(panel_config->power_on_delay); | ||
555 | |||
556 | for (i = 0; i < panel_data->num_gpios; ++i) { | ||
557 | gpio_set_value_cansleep(panel_data->gpios[i], | ||
558 | panel_data->gpio_invert[i] ? 0 : 1); | ||
559 | } | ||
560 | |||
561 | return 0; | ||
562 | |||
563 | err0: | ||
564 | return r; | ||
565 | } | ||
566 | |||
567 | static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev) | ||
568 | { | ||
569 | struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); | ||
570 | struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); | ||
571 | struct panel_config *panel_config = drv_data->panel_config; | ||
572 | int i; | ||
573 | |||
574 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
575 | return; | ||
576 | |||
577 | for (i = panel_data->num_gpios - 1; i >= 0; --i) { | ||
578 | gpio_set_value_cansleep(panel_data->gpios[i], | ||
579 | panel_data->gpio_invert[i] ? 1 : 0); | ||
580 | } | ||
581 | |||
582 | /* wait couple of vsyncs after disabling the LCD */ | ||
583 | if (panel_config->power_off_delay) | ||
584 | msleep(panel_config->power_off_delay); | ||
585 | |||
586 | omapdss_dpi_display_disable(dssdev); | ||
587 | } | ||
588 | |||
589 | static int generic_dpi_panel_probe(struct omap_dss_device *dssdev) | ||
590 | { | ||
591 | struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); | ||
592 | struct panel_config *panel_config = NULL; | ||
593 | struct panel_drv_data *drv_data = NULL; | ||
594 | int i, r; | ||
595 | |||
596 | dev_dbg(dssdev->dev, "probe\n"); | ||
597 | |||
598 | if (!panel_data || !panel_data->name) | ||
599 | return -EINVAL; | ||
600 | |||
601 | for (i = 0; i < ARRAY_SIZE(generic_dpi_panels); i++) { | ||
602 | if (strcmp(panel_data->name, generic_dpi_panels[i].name) == 0) { | ||
603 | panel_config = &generic_dpi_panels[i]; | ||
604 | break; | ||
605 | } | ||
606 | } | ||
607 | |||
608 | if (!panel_config) | ||
609 | return -EINVAL; | ||
610 | |||
611 | for (i = 0; i < panel_data->num_gpios; ++i) { | ||
612 | r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i], | ||
613 | panel_data->gpio_invert[i] ? | ||
614 | GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, | ||
615 | "panel gpio"); | ||
616 | if (r) | ||
617 | return r; | ||
618 | } | ||
619 | |||
620 | dssdev->panel.timings = panel_config->timings; | ||
621 | |||
622 | drv_data = devm_kzalloc(dssdev->dev, sizeof(*drv_data), GFP_KERNEL); | ||
623 | if (!drv_data) | ||
624 | return -ENOMEM; | ||
625 | |||
626 | drv_data->dssdev = dssdev; | ||
627 | drv_data->panel_config = panel_config; | ||
628 | |||
629 | mutex_init(&drv_data->lock); | ||
630 | |||
631 | dev_set_drvdata(dssdev->dev, drv_data); | ||
632 | |||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev) | ||
637 | { | ||
638 | dev_dbg(dssdev->dev, "remove\n"); | ||
639 | |||
640 | dev_set_drvdata(dssdev->dev, NULL); | ||
641 | } | ||
642 | |||
643 | static int generic_dpi_panel_enable(struct omap_dss_device *dssdev) | ||
644 | { | ||
645 | struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); | ||
646 | int r; | ||
647 | |||
648 | mutex_lock(&drv_data->lock); | ||
649 | |||
650 | r = generic_dpi_panel_power_on(dssdev); | ||
651 | if (r) | ||
652 | goto err; | ||
653 | |||
654 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
655 | err: | ||
656 | mutex_unlock(&drv_data->lock); | ||
657 | |||
658 | return r; | ||
659 | } | ||
660 | |||
661 | static void generic_dpi_panel_disable(struct omap_dss_device *dssdev) | ||
662 | { | ||
663 | struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); | ||
664 | |||
665 | mutex_lock(&drv_data->lock); | ||
666 | |||
667 | generic_dpi_panel_power_off(dssdev); | ||
668 | |||
669 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
670 | |||
671 | mutex_unlock(&drv_data->lock); | ||
672 | } | ||
673 | |||
674 | static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, | ||
675 | struct omap_video_timings *timings) | ||
676 | { | ||
677 | struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); | ||
678 | |||
679 | mutex_lock(&drv_data->lock); | ||
680 | |||
681 | omapdss_dpi_set_timings(dssdev, timings); | ||
682 | |||
683 | dssdev->panel.timings = *timings; | ||
684 | |||
685 | mutex_unlock(&drv_data->lock); | ||
686 | } | ||
687 | |||
688 | static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev, | ||
689 | struct omap_video_timings *timings) | ||
690 | { | ||
691 | struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); | ||
692 | |||
693 | mutex_lock(&drv_data->lock); | ||
694 | |||
695 | *timings = dssdev->panel.timings; | ||
696 | |||
697 | mutex_unlock(&drv_data->lock); | ||
698 | } | ||
699 | |||
700 | static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, | ||
701 | struct omap_video_timings *timings) | ||
702 | { | ||
703 | struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); | ||
704 | int r; | ||
705 | |||
706 | mutex_lock(&drv_data->lock); | ||
707 | |||
708 | r = dpi_check_timings(dssdev, timings); | ||
709 | |||
710 | mutex_unlock(&drv_data->lock); | ||
711 | |||
712 | return r; | ||
713 | } | ||
714 | |||
715 | static struct omap_dss_driver dpi_driver = { | ||
716 | .probe = generic_dpi_panel_probe, | ||
717 | .remove = __exit_p(generic_dpi_panel_remove), | ||
718 | |||
719 | .enable = generic_dpi_panel_enable, | ||
720 | .disable = generic_dpi_panel_disable, | ||
721 | |||
722 | .set_timings = generic_dpi_panel_set_timings, | ||
723 | .get_timings = generic_dpi_panel_get_timings, | ||
724 | .check_timings = generic_dpi_panel_check_timings, | ||
725 | |||
726 | .driver = { | ||
727 | .name = "generic_dpi_panel", | ||
728 | .owner = THIS_MODULE, | ||
729 | }, | ||
730 | }; | ||
731 | |||
732 | static int __init generic_dpi_panel_drv_init(void) | ||
733 | { | ||
734 | return omap_dss_register_driver(&dpi_driver); | ||
735 | } | ||
736 | |||
737 | static void __exit generic_dpi_panel_drv_exit(void) | ||
738 | { | ||
739 | omap_dss_unregister_driver(&dpi_driver); | ||
740 | } | ||
741 | |||
742 | module_init(generic_dpi_panel_drv_init); | ||
743 | module_exit(generic_dpi_panel_drv_exit); | ||
744 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c deleted file mode 100644 index 6c51430ddb37..000000000000 --- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +++ /dev/null | |||
@@ -1,262 +0,0 @@ | |||
1 | /* | ||
2 | * LCD panel driver for LG.Philips LB035Q02 | ||
3 | * | ||
4 | * Author: Steve Sakoman <steve@sakoman.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/spi/spi.h> | ||
22 | #include <linux/mutex.h> | ||
23 | #include <linux/gpio.h> | ||
24 | |||
25 | #include <video/omapdss.h> | ||
26 | #include <video/omap-panel-data.h> | ||
27 | |||
28 | struct lb035q02_data { | ||
29 | struct mutex lock; | ||
30 | }; | ||
31 | |||
32 | static struct omap_video_timings lb035q02_timings = { | ||
33 | .x_res = 320, | ||
34 | .y_res = 240, | ||
35 | |||
36 | .pixel_clock = 6500, | ||
37 | |||
38 | .hsw = 2, | ||
39 | .hfp = 20, | ||
40 | .hbp = 68, | ||
41 | |||
42 | .vsw = 2, | ||
43 | .vfp = 4, | ||
44 | .vbp = 18, | ||
45 | |||
46 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
47 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
48 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
49 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
50 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
51 | }; | ||
52 | |||
53 | static inline struct panel_generic_dpi_data | ||
54 | *get_panel_data(const struct omap_dss_device *dssdev) | ||
55 | { | ||
56 | return (struct panel_generic_dpi_data *) dssdev->data; | ||
57 | } | ||
58 | |||
59 | static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) | ||
60 | { | ||
61 | struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); | ||
62 | int r, i; | ||
63 | |||
64 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
65 | return 0; | ||
66 | |||
67 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
68 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
69 | |||
70 | r = omapdss_dpi_display_enable(dssdev); | ||
71 | if (r) | ||
72 | goto err0; | ||
73 | |||
74 | for (i = 0; i < panel_data->num_gpios; ++i) { | ||
75 | gpio_set_value_cansleep(panel_data->gpios[i], | ||
76 | panel_data->gpio_invert[i] ? 0 : 1); | ||
77 | } | ||
78 | |||
79 | return 0; | ||
80 | |||
81 | err0: | ||
82 | return r; | ||
83 | } | ||
84 | |||
85 | static void lb035q02_panel_power_off(struct omap_dss_device *dssdev) | ||
86 | { | ||
87 | struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); | ||
88 | int i; | ||
89 | |||
90 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
91 | return; | ||
92 | |||
93 | for (i = panel_data->num_gpios - 1; i >= 0; --i) { | ||
94 | gpio_set_value_cansleep(panel_data->gpios[i], | ||
95 | panel_data->gpio_invert[i] ? 1 : 0); | ||
96 | } | ||
97 | |||
98 | omapdss_dpi_display_disable(dssdev); | ||
99 | } | ||
100 | |||
101 | static int lb035q02_panel_probe(struct omap_dss_device *dssdev) | ||
102 | { | ||
103 | struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); | ||
104 | struct lb035q02_data *ld; | ||
105 | int r, i; | ||
106 | |||
107 | if (!panel_data) | ||
108 | return -EINVAL; | ||
109 | |||
110 | dssdev->panel.timings = lb035q02_timings; | ||
111 | |||
112 | ld = devm_kzalloc(dssdev->dev, sizeof(*ld), GFP_KERNEL); | ||
113 | if (!ld) | ||
114 | return -ENOMEM; | ||
115 | |||
116 | for (i = 0; i < panel_data->num_gpios; ++i) { | ||
117 | r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i], | ||
118 | panel_data->gpio_invert[i] ? | ||
119 | GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, | ||
120 | "panel gpio"); | ||
121 | if (r) | ||
122 | return r; | ||
123 | } | ||
124 | |||
125 | mutex_init(&ld->lock); | ||
126 | dev_set_drvdata(dssdev->dev, ld); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void lb035q02_panel_remove(struct omap_dss_device *dssdev) | ||
132 | { | ||
133 | } | ||
134 | |||
135 | static int lb035q02_panel_enable(struct omap_dss_device *dssdev) | ||
136 | { | ||
137 | struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev); | ||
138 | int r; | ||
139 | |||
140 | mutex_lock(&ld->lock); | ||
141 | |||
142 | r = lb035q02_panel_power_on(dssdev); | ||
143 | if (r) | ||
144 | goto err; | ||
145 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
146 | |||
147 | mutex_unlock(&ld->lock); | ||
148 | return 0; | ||
149 | err: | ||
150 | mutex_unlock(&ld->lock); | ||
151 | return r; | ||
152 | } | ||
153 | |||
154 | static void lb035q02_panel_disable(struct omap_dss_device *dssdev) | ||
155 | { | ||
156 | struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev); | ||
157 | |||
158 | mutex_lock(&ld->lock); | ||
159 | |||
160 | lb035q02_panel_power_off(dssdev); | ||
161 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
162 | |||
163 | mutex_unlock(&ld->lock); | ||
164 | } | ||
165 | |||
166 | static struct omap_dss_driver lb035q02_driver = { | ||
167 | .probe = lb035q02_panel_probe, | ||
168 | .remove = lb035q02_panel_remove, | ||
169 | |||
170 | .enable = lb035q02_panel_enable, | ||
171 | .disable = lb035q02_panel_disable, | ||
172 | |||
173 | .driver = { | ||
174 | .name = "lgphilips_lb035q02_panel", | ||
175 | .owner = THIS_MODULE, | ||
176 | }, | ||
177 | }; | ||
178 | |||
179 | static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val) | ||
180 | { | ||
181 | struct spi_message msg; | ||
182 | struct spi_transfer index_xfer = { | ||
183 | .len = 3, | ||
184 | .cs_change = 1, | ||
185 | }; | ||
186 | struct spi_transfer value_xfer = { | ||
187 | .len = 3, | ||
188 | }; | ||
189 | u8 buffer[16]; | ||
190 | |||
191 | spi_message_init(&msg); | ||
192 | |||
193 | /* register index */ | ||
194 | buffer[0] = 0x70; | ||
195 | buffer[1] = 0x00; | ||
196 | buffer[2] = reg & 0x7f; | ||
197 | index_xfer.tx_buf = buffer; | ||
198 | spi_message_add_tail(&index_xfer, &msg); | ||
199 | |||
200 | /* register value */ | ||
201 | buffer[4] = 0x72; | ||
202 | buffer[5] = val >> 8; | ||
203 | buffer[6] = val; | ||
204 | value_xfer.tx_buf = buffer + 4; | ||
205 | spi_message_add_tail(&value_xfer, &msg); | ||
206 | |||
207 | return spi_sync(spi, &msg); | ||
208 | } | ||
209 | |||
210 | static void init_lb035q02_panel(struct spi_device *spi) | ||
211 | { | ||
212 | /* Init sequence from page 28 of the lb035q02 spec */ | ||
213 | lb035q02_write_reg(spi, 0x01, 0x6300); | ||
214 | lb035q02_write_reg(spi, 0x02, 0x0200); | ||
215 | lb035q02_write_reg(spi, 0x03, 0x0177); | ||
216 | lb035q02_write_reg(spi, 0x04, 0x04c7); | ||
217 | lb035q02_write_reg(spi, 0x05, 0xffc0); | ||
218 | lb035q02_write_reg(spi, 0x06, 0xe806); | ||
219 | lb035q02_write_reg(spi, 0x0a, 0x4008); | ||
220 | lb035q02_write_reg(spi, 0x0b, 0x0000); | ||
221 | lb035q02_write_reg(spi, 0x0d, 0x0030); | ||
222 | lb035q02_write_reg(spi, 0x0e, 0x2800); | ||
223 | lb035q02_write_reg(spi, 0x0f, 0x0000); | ||
224 | lb035q02_write_reg(spi, 0x16, 0x9f80); | ||
225 | lb035q02_write_reg(spi, 0x17, 0x0a0f); | ||
226 | lb035q02_write_reg(spi, 0x1e, 0x00c1); | ||
227 | lb035q02_write_reg(spi, 0x30, 0x0300); | ||
228 | lb035q02_write_reg(spi, 0x31, 0x0007); | ||
229 | lb035q02_write_reg(spi, 0x32, 0x0000); | ||
230 | lb035q02_write_reg(spi, 0x33, 0x0000); | ||
231 | lb035q02_write_reg(spi, 0x34, 0x0707); | ||
232 | lb035q02_write_reg(spi, 0x35, 0x0004); | ||
233 | lb035q02_write_reg(spi, 0x36, 0x0302); | ||
234 | lb035q02_write_reg(spi, 0x37, 0x0202); | ||
235 | lb035q02_write_reg(spi, 0x3a, 0x0a0d); | ||
236 | lb035q02_write_reg(spi, 0x3b, 0x0806); | ||
237 | } | ||
238 | |||
239 | static int lb035q02_panel_spi_probe(struct spi_device *spi) | ||
240 | { | ||
241 | init_lb035q02_panel(spi); | ||
242 | return omap_dss_register_driver(&lb035q02_driver); | ||
243 | } | ||
244 | |||
245 | static int lb035q02_panel_spi_remove(struct spi_device *spi) | ||
246 | { | ||
247 | omap_dss_unregister_driver(&lb035q02_driver); | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static struct spi_driver lb035q02_spi_driver = { | ||
252 | .driver = { | ||
253 | .name = "lgphilips_lb035q02_panel-spi", | ||
254 | .owner = THIS_MODULE, | ||
255 | }, | ||
256 | .probe = lb035q02_panel_spi_probe, | ||
257 | .remove = lb035q02_panel_spi_remove, | ||
258 | }; | ||
259 | |||
260 | module_spi_driver(lb035q02_spi_driver); | ||
261 | |||
262 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c deleted file mode 100644 index 1d525fc84db9..000000000000 --- a/drivers/video/omap2/displays/panel-n8x0.c +++ /dev/null | |||
@@ -1,616 +0,0 @@ | |||
1 | /* #define DEBUG */ | ||
2 | |||
3 | #include <linux/module.h> | ||
4 | #include <linux/delay.h> | ||
5 | #include <linux/slab.h> | ||
6 | #include <linux/gpio.h> | ||
7 | #include <linux/spi/spi.h> | ||
8 | #include <linux/fb.h> | ||
9 | |||
10 | #include <video/omapdss.h> | ||
11 | #include <video/omap-panel-data.h> | ||
12 | |||
13 | #define BLIZZARD_REV_CODE 0x00 | ||
14 | #define BLIZZARD_CONFIG 0x02 | ||
15 | #define BLIZZARD_PLL_DIV 0x04 | ||
16 | #define BLIZZARD_PLL_LOCK_RANGE 0x06 | ||
17 | #define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08 | ||
18 | #define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a | ||
19 | #define BLIZZARD_PLL_MODE 0x0c | ||
20 | #define BLIZZARD_CLK_SRC 0x0e | ||
21 | #define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 | ||
22 | #define BLIZZARD_MEM_BANK0_STATUS 0x14 | ||
23 | #define BLIZZARD_PANEL_CONFIGURATION 0x28 | ||
24 | #define BLIZZARD_HDISP 0x2a | ||
25 | #define BLIZZARD_HNDP 0x2c | ||
26 | #define BLIZZARD_VDISP0 0x2e | ||
27 | #define BLIZZARD_VDISP1 0x30 | ||
28 | #define BLIZZARD_VNDP 0x32 | ||
29 | #define BLIZZARD_HSW 0x34 | ||
30 | #define BLIZZARD_VSW 0x38 | ||
31 | #define BLIZZARD_DISPLAY_MODE 0x68 | ||
32 | #define BLIZZARD_INPUT_WIN_X_START_0 0x6c | ||
33 | #define BLIZZARD_DATA_SOURCE_SELECT 0x8e | ||
34 | #define BLIZZARD_DISP_MEM_DATA_PORT 0x90 | ||
35 | #define BLIZZARD_DISP_MEM_READ_ADDR0 0x92 | ||
36 | #define BLIZZARD_POWER_SAVE 0xE6 | ||
37 | #define BLIZZARD_NDISP_CTRL_STATUS 0xE8 | ||
38 | |||
39 | /* Data source select */ | ||
40 | /* For S1D13745 */ | ||
41 | #define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00 | ||
42 | #define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01 | ||
43 | #define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04 | ||
44 | #define BLIZZARD_SRC_DISABLE_OVERLAY 0x05 | ||
45 | /* For S1D13744 */ | ||
46 | #define BLIZZARD_SRC_WRITE_LCD 0x00 | ||
47 | #define BLIZZARD_SRC_BLT_LCD 0x06 | ||
48 | |||
49 | #define BLIZZARD_COLOR_RGB565 0x01 | ||
50 | #define BLIZZARD_COLOR_YUV420 0x09 | ||
51 | |||
52 | #define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */ | ||
53 | #define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */ | ||
54 | |||
55 | #define MIPID_CMD_READ_DISP_ID 0x04 | ||
56 | #define MIPID_CMD_READ_RED 0x06 | ||
57 | #define MIPID_CMD_READ_GREEN 0x07 | ||
58 | #define MIPID_CMD_READ_BLUE 0x08 | ||
59 | #define MIPID_CMD_READ_DISP_STATUS 0x09 | ||
60 | #define MIPID_CMD_RDDSDR 0x0F | ||
61 | #define MIPID_CMD_SLEEP_IN 0x10 | ||
62 | #define MIPID_CMD_SLEEP_OUT 0x11 | ||
63 | #define MIPID_CMD_DISP_OFF 0x28 | ||
64 | #define MIPID_CMD_DISP_ON 0x29 | ||
65 | |||
66 | static struct panel_drv_data { | ||
67 | struct mutex lock; | ||
68 | |||
69 | struct omap_dss_device *dssdev; | ||
70 | struct spi_device *spidev; | ||
71 | |||
72 | int blizzard_ver; | ||
73 | } s_drv_data; | ||
74 | |||
75 | |||
76 | static inline | ||
77 | struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev) | ||
78 | { | ||
79 | return dssdev->data; | ||
80 | } | ||
81 | |||
82 | static inline | ||
83 | struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev) | ||
84 | { | ||
85 | return &s_drv_data; | ||
86 | } | ||
87 | |||
88 | |||
89 | static inline void blizzard_cmd(u8 cmd) | ||
90 | { | ||
91 | omap_rfbi_write_command(&cmd, 1); | ||
92 | } | ||
93 | |||
94 | static inline void blizzard_write(u8 cmd, const u8 *buf, int len) | ||
95 | { | ||
96 | omap_rfbi_write_command(&cmd, 1); | ||
97 | omap_rfbi_write_data(buf, len); | ||
98 | } | ||
99 | |||
100 | static inline void blizzard_read(u8 cmd, u8 *buf, int len) | ||
101 | { | ||
102 | omap_rfbi_write_command(&cmd, 1); | ||
103 | omap_rfbi_read_data(buf, len); | ||
104 | } | ||
105 | |||
106 | static u8 blizzard_read_reg(u8 cmd) | ||
107 | { | ||
108 | u8 data; | ||
109 | blizzard_read(cmd, &data, 1); | ||
110 | return data; | ||
111 | } | ||
112 | |||
113 | static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev, | ||
114 | int x, int y, int w, int h) | ||
115 | { | ||
116 | struct panel_drv_data *ddata = get_drv_data(dssdev); | ||
117 | u8 tmp[18]; | ||
118 | int x_end, y_end; | ||
119 | |||
120 | x_end = x + w - 1; | ||
121 | y_end = y + h - 1; | ||
122 | |||
123 | tmp[0] = x; | ||
124 | tmp[1] = x >> 8; | ||
125 | tmp[2] = y; | ||
126 | tmp[3] = y >> 8; | ||
127 | tmp[4] = x_end; | ||
128 | tmp[5] = x_end >> 8; | ||
129 | tmp[6] = y_end; | ||
130 | tmp[7] = y_end >> 8; | ||
131 | |||
132 | /* scaling? */ | ||
133 | tmp[8] = x; | ||
134 | tmp[9] = x >> 8; | ||
135 | tmp[10] = y; | ||
136 | tmp[11] = y >> 8; | ||
137 | tmp[12] = x_end; | ||
138 | tmp[13] = x_end >> 8; | ||
139 | tmp[14] = y_end; | ||
140 | tmp[15] = y_end >> 8; | ||
141 | |||
142 | tmp[16] = BLIZZARD_COLOR_RGB565; | ||
143 | |||
144 | if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745) | ||
145 | tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND; | ||
146 | else | ||
147 | tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ? | ||
148 | BLIZZARD_SRC_WRITE_LCD : | ||
149 | BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE; | ||
150 | |||
151 | omapdss_rfbi_set_pixel_size(dssdev, 16); | ||
152 | omapdss_rfbi_set_data_lines(dssdev, 8); | ||
153 | |||
154 | omap_rfbi_configure(dssdev); | ||
155 | |||
156 | blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18); | ||
157 | |||
158 | omapdss_rfbi_set_pixel_size(dssdev, 16); | ||
159 | omapdss_rfbi_set_data_lines(dssdev, 16); | ||
160 | |||
161 | omap_rfbi_configure(dssdev); | ||
162 | } | ||
163 | |||
164 | static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf, | ||
165 | int wlen, u8 *rbuf, int rlen) | ||
166 | { | ||
167 | struct spi_message m; | ||
168 | struct spi_transfer *x, xfer[4]; | ||
169 | u16 w; | ||
170 | int r; | ||
171 | |||
172 | spi_message_init(&m); | ||
173 | |||
174 | memset(xfer, 0, sizeof(xfer)); | ||
175 | x = &xfer[0]; | ||
176 | |||
177 | cmd &= 0xff; | ||
178 | x->tx_buf = &cmd; | ||
179 | x->bits_per_word = 9; | ||
180 | x->len = 2; | ||
181 | spi_message_add_tail(x, &m); | ||
182 | |||
183 | if (wlen) { | ||
184 | x++; | ||
185 | x->tx_buf = wbuf; | ||
186 | x->len = wlen; | ||
187 | x->bits_per_word = 9; | ||
188 | spi_message_add_tail(x, &m); | ||
189 | } | ||
190 | |||
191 | if (rlen) { | ||
192 | x++; | ||
193 | x->rx_buf = &w; | ||
194 | x->len = 1; | ||
195 | spi_message_add_tail(x, &m); | ||
196 | |||
197 | if (rlen > 1) { | ||
198 | /* Arrange for the extra clock before the first | ||
199 | * data bit. | ||
200 | */ | ||
201 | x->bits_per_word = 9; | ||
202 | x->len = 2; | ||
203 | |||
204 | x++; | ||
205 | x->rx_buf = &rbuf[1]; | ||
206 | x->len = rlen - 1; | ||
207 | spi_message_add_tail(x, &m); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | r = spi_sync(spi, &m); | ||
212 | if (r < 0) | ||
213 | dev_dbg(&spi->dev, "spi_sync %d\n", r); | ||
214 | |||
215 | if (rlen) | ||
216 | rbuf[0] = w & 0xff; | ||
217 | } | ||
218 | |||
219 | static inline void mipid_cmd(struct spi_device *spi, int cmd) | ||
220 | { | ||
221 | mipid_transfer(spi, cmd, NULL, 0, NULL, 0); | ||
222 | } | ||
223 | |||
224 | static inline void mipid_write(struct spi_device *spi, | ||
225 | int reg, const u8 *buf, int len) | ||
226 | { | ||
227 | mipid_transfer(spi, reg, buf, len, NULL, 0); | ||
228 | } | ||
229 | |||
230 | static inline void mipid_read(struct spi_device *spi, | ||
231 | int reg, u8 *buf, int len) | ||
232 | { | ||
233 | mipid_transfer(spi, reg, NULL, 0, buf, len); | ||
234 | } | ||
235 | |||
236 | static void set_data_lines(struct spi_device *spi, int data_lines) | ||
237 | { | ||
238 | u16 par; | ||
239 | |||
240 | switch (data_lines) { | ||
241 | case 16: | ||
242 | par = 0x150; | ||
243 | break; | ||
244 | case 18: | ||
245 | par = 0x160; | ||
246 | break; | ||
247 | case 24: | ||
248 | par = 0x170; | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | mipid_write(spi, 0x3a, (u8 *)&par, 2); | ||
253 | } | ||
254 | |||
255 | static void send_init_string(struct spi_device *spi) | ||
256 | { | ||
257 | u16 initpar[] = { 0x0102, 0x0100, 0x0100 }; | ||
258 | mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar)); | ||
259 | } | ||
260 | |||
261 | static void send_display_on(struct spi_device *spi) | ||
262 | { | ||
263 | mipid_cmd(spi, MIPID_CMD_DISP_ON); | ||
264 | } | ||
265 | |||
266 | static void send_display_off(struct spi_device *spi) | ||
267 | { | ||
268 | mipid_cmd(spi, MIPID_CMD_DISP_OFF); | ||
269 | } | ||
270 | |||
271 | static void send_sleep_out(struct spi_device *spi) | ||
272 | { | ||
273 | mipid_cmd(spi, MIPID_CMD_SLEEP_OUT); | ||
274 | msleep(120); | ||
275 | } | ||
276 | |||
277 | static void send_sleep_in(struct spi_device *spi) | ||
278 | { | ||
279 | mipid_cmd(spi, MIPID_CMD_SLEEP_IN); | ||
280 | msleep(50); | ||
281 | } | ||
282 | |||
283 | static int n8x0_panel_power_on(struct omap_dss_device *dssdev) | ||
284 | { | ||
285 | int r; | ||
286 | struct panel_n8x0_data *bdata = get_board_data(dssdev); | ||
287 | struct panel_drv_data *ddata = get_drv_data(dssdev); | ||
288 | struct spi_device *spi = ddata->spidev; | ||
289 | u8 rev, conf; | ||
290 | u8 display_id[3]; | ||
291 | const char *panel_name; | ||
292 | |||
293 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
294 | return 0; | ||
295 | |||
296 | gpio_direction_output(bdata->ctrl_pwrdown, 1); | ||
297 | |||
298 | omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res, | ||
299 | dssdev->panel.timings.y_res); | ||
300 | omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size); | ||
301 | omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines); | ||
302 | omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings); | ||
303 | |||
304 | r = omapdss_rfbi_display_enable(dssdev); | ||
305 | if (r) | ||
306 | goto err_rfbi_en; | ||
307 | |||
308 | rev = blizzard_read_reg(BLIZZARD_REV_CODE); | ||
309 | conf = blizzard_read_reg(BLIZZARD_CONFIG); | ||
310 | |||
311 | switch (rev & 0xfc) { | ||
312 | case 0x9c: | ||
313 | ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744; | ||
314 | dev_info(dssdev->dev, "s1d13744 LCD controller rev %d " | ||
315 | "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); | ||
316 | break; | ||
317 | case 0xa4: | ||
318 | ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745; | ||
319 | dev_info(dssdev->dev, "s1d13745 LCD controller rev %d " | ||
320 | "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); | ||
321 | break; | ||
322 | default: | ||
323 | dev_err(dssdev->dev, "invalid s1d1374x revision %02x\n", rev); | ||
324 | r = -ENODEV; | ||
325 | goto err_inv_chip; | ||
326 | } | ||
327 | |||
328 | /* panel */ | ||
329 | |||
330 | gpio_direction_output(bdata->panel_reset, 1); | ||
331 | |||
332 | mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3); | ||
333 | dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n", | ||
334 | display_id[0], display_id[1], display_id[2]); | ||
335 | |||
336 | switch (display_id[0]) { | ||
337 | case 0x45: | ||
338 | panel_name = "lph8923"; | ||
339 | break; | ||
340 | case 0x83: | ||
341 | panel_name = "ls041y3"; | ||
342 | break; | ||
343 | default: | ||
344 | dev_err(dssdev->dev, "invalid display ID 0x%x\n", | ||
345 | display_id[0]); | ||
346 | r = -ENODEV; | ||
347 | goto err_inv_panel; | ||
348 | } | ||
349 | |||
350 | dev_info(dssdev->dev, "%s rev %02x LCD detected\n", | ||
351 | panel_name, display_id[1]); | ||
352 | |||
353 | send_sleep_out(spi); | ||
354 | send_init_string(spi); | ||
355 | set_data_lines(spi, 24); | ||
356 | send_display_on(spi); | ||
357 | |||
358 | return 0; | ||
359 | |||
360 | err_inv_panel: | ||
361 | /* | ||
362 | * HACK: we should turn off the panel here, but there is some problem | ||
363 | * with the initialization sequence, and we fail to init the panel if we | ||
364 | * have turned it off | ||
365 | */ | ||
366 | /* gpio_direction_output(bdata->panel_reset, 0); */ | ||
367 | err_inv_chip: | ||
368 | omapdss_rfbi_display_disable(dssdev); | ||
369 | err_rfbi_en: | ||
370 | gpio_direction_output(bdata->ctrl_pwrdown, 0); | ||
371 | return r; | ||
372 | } | ||
373 | |||
374 | static void n8x0_panel_power_off(struct omap_dss_device *dssdev) | ||
375 | { | ||
376 | struct panel_n8x0_data *bdata = get_board_data(dssdev); | ||
377 | struct panel_drv_data *ddata = get_drv_data(dssdev); | ||
378 | struct spi_device *spi = ddata->spidev; | ||
379 | |||
380 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
381 | return; | ||
382 | |||
383 | send_display_off(spi); | ||
384 | send_sleep_in(spi); | ||
385 | |||
386 | /* | ||
387 | * HACK: we should turn off the panel here, but there is some problem | ||
388 | * with the initialization sequence, and we fail to init the panel if we | ||
389 | * have turned it off | ||
390 | */ | ||
391 | /* gpio_direction_output(bdata->panel_reset, 0); */ | ||
392 | gpio_direction_output(bdata->ctrl_pwrdown, 0); | ||
393 | omapdss_rfbi_display_disable(dssdev); | ||
394 | } | ||
395 | |||
396 | static const struct rfbi_timings n8x0_panel_timings = { | ||
397 | .cs_on_time = 0, | ||
398 | |||
399 | .we_on_time = 9000, | ||
400 | .we_off_time = 18000, | ||
401 | .we_cycle_time = 36000, | ||
402 | |||
403 | .re_on_time = 9000, | ||
404 | .re_off_time = 27000, | ||
405 | .re_cycle_time = 36000, | ||
406 | |||
407 | .access_time = 27000, | ||
408 | .cs_off_time = 36000, | ||
409 | |||
410 | .cs_pulse_width = 0, | ||
411 | }; | ||
412 | |||
413 | static int n8x0_panel_probe(struct omap_dss_device *dssdev) | ||
414 | { | ||
415 | struct panel_n8x0_data *bdata = get_board_data(dssdev); | ||
416 | struct panel_drv_data *ddata; | ||
417 | int r; | ||
418 | |||
419 | dev_dbg(dssdev->dev, "probe\n"); | ||
420 | |||
421 | if (!bdata) | ||
422 | return -EINVAL; | ||
423 | |||
424 | s_drv_data.dssdev = dssdev; | ||
425 | |||
426 | ddata = &s_drv_data; | ||
427 | |||
428 | mutex_init(&ddata->lock); | ||
429 | |||
430 | dssdev->panel.timings.x_res = 800; | ||
431 | dssdev->panel.timings.y_res = 480; | ||
432 | dssdev->ctrl.pixel_size = 16; | ||
433 | dssdev->ctrl.rfbi_timings = n8x0_panel_timings; | ||
434 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; | ||
435 | |||
436 | if (gpio_is_valid(bdata->panel_reset)) { | ||
437 | r = devm_gpio_request_one(dssdev->dev, bdata->panel_reset, | ||
438 | GPIOF_OUT_INIT_LOW, "PANEL RESET"); | ||
439 | if (r) | ||
440 | return r; | ||
441 | } | ||
442 | |||
443 | if (gpio_is_valid(bdata->ctrl_pwrdown)) { | ||
444 | r = devm_gpio_request_one(dssdev->dev, bdata->ctrl_pwrdown, | ||
445 | GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN"); | ||
446 | if (r) | ||
447 | return r; | ||
448 | } | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | static void n8x0_panel_remove(struct omap_dss_device *dssdev) | ||
454 | { | ||
455 | dev_dbg(dssdev->dev, "remove\n"); | ||
456 | |||
457 | dev_set_drvdata(dssdev->dev, NULL); | ||
458 | } | ||
459 | |||
460 | static int n8x0_panel_enable(struct omap_dss_device *dssdev) | ||
461 | { | ||
462 | struct panel_drv_data *ddata = get_drv_data(dssdev); | ||
463 | int r; | ||
464 | |||
465 | dev_dbg(dssdev->dev, "enable\n"); | ||
466 | |||
467 | mutex_lock(&ddata->lock); | ||
468 | |||
469 | rfbi_bus_lock(); | ||
470 | |||
471 | r = n8x0_panel_power_on(dssdev); | ||
472 | |||
473 | rfbi_bus_unlock(); | ||
474 | |||
475 | if (r) { | ||
476 | mutex_unlock(&ddata->lock); | ||
477 | return r; | ||
478 | } | ||
479 | |||
480 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
481 | |||
482 | mutex_unlock(&ddata->lock); | ||
483 | |||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static void n8x0_panel_disable(struct omap_dss_device *dssdev) | ||
488 | { | ||
489 | struct panel_drv_data *ddata = get_drv_data(dssdev); | ||
490 | |||
491 | dev_dbg(dssdev->dev, "disable\n"); | ||
492 | |||
493 | mutex_lock(&ddata->lock); | ||
494 | |||
495 | rfbi_bus_lock(); | ||
496 | |||
497 | n8x0_panel_power_off(dssdev); | ||
498 | |||
499 | rfbi_bus_unlock(); | ||
500 | |||
501 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
502 | |||
503 | mutex_unlock(&ddata->lock); | ||
504 | } | ||
505 | |||
506 | static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, | ||
507 | u16 *xres, u16 *yres) | ||
508 | { | ||
509 | *xres = dssdev->panel.timings.x_res; | ||
510 | *yres = dssdev->panel.timings.y_res; | ||
511 | } | ||
512 | |||
513 | static void update_done(void *data) | ||
514 | { | ||
515 | rfbi_bus_unlock(); | ||
516 | } | ||
517 | |||
518 | static int n8x0_panel_update(struct omap_dss_device *dssdev, | ||
519 | u16 x, u16 y, u16 w, u16 h) | ||
520 | { | ||
521 | struct panel_drv_data *ddata = get_drv_data(dssdev); | ||
522 | u16 dw, dh; | ||
523 | |||
524 | dev_dbg(dssdev->dev, "update\n"); | ||
525 | |||
526 | dw = dssdev->panel.timings.x_res; | ||
527 | dh = dssdev->panel.timings.y_res; | ||
528 | |||
529 | if (x != 0 || y != 0 || w != dw || h != dh) { | ||
530 | dev_err(dssdev->dev, "invalid update region %d, %d, %d, %d\n", | ||
531 | x, y, w, h); | ||
532 | return -EINVAL; | ||
533 | } | ||
534 | |||
535 | mutex_lock(&ddata->lock); | ||
536 | rfbi_bus_lock(); | ||
537 | |||
538 | blizzard_ctrl_setup_update(dssdev, x, y, w, h); | ||
539 | |||
540 | omap_rfbi_update(dssdev, update_done, NULL); | ||
541 | |||
542 | mutex_unlock(&ddata->lock); | ||
543 | |||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | static int n8x0_panel_sync(struct omap_dss_device *dssdev) | ||
548 | { | ||
549 | struct panel_drv_data *ddata = get_drv_data(dssdev); | ||
550 | |||
551 | dev_dbg(dssdev->dev, "sync\n"); | ||
552 | |||
553 | mutex_lock(&ddata->lock); | ||
554 | rfbi_bus_lock(); | ||
555 | rfbi_bus_unlock(); | ||
556 | mutex_unlock(&ddata->lock); | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static struct omap_dss_driver n8x0_panel_driver = { | ||
562 | .probe = n8x0_panel_probe, | ||
563 | .remove = n8x0_panel_remove, | ||
564 | |||
565 | .enable = n8x0_panel_enable, | ||
566 | .disable = n8x0_panel_disable, | ||
567 | |||
568 | .update = n8x0_panel_update, | ||
569 | .sync = n8x0_panel_sync, | ||
570 | |||
571 | .get_resolution = n8x0_panel_get_resolution, | ||
572 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, | ||
573 | |||
574 | .driver = { | ||
575 | .name = "n8x0_panel", | ||
576 | .owner = THIS_MODULE, | ||
577 | }, | ||
578 | }; | ||
579 | |||
580 | /* PANEL */ | ||
581 | |||
582 | static int mipid_spi_probe(struct spi_device *spi) | ||
583 | { | ||
584 | int r; | ||
585 | |||
586 | dev_dbg(&spi->dev, "mipid_spi_probe\n"); | ||
587 | |||
588 | spi->mode = SPI_MODE_0; | ||
589 | |||
590 | s_drv_data.spidev = spi; | ||
591 | |||
592 | r = omap_dss_register_driver(&n8x0_panel_driver); | ||
593 | if (r) | ||
594 | pr_err("n8x0_panel: dss driver registration failed\n"); | ||
595 | |||
596 | return r; | ||
597 | } | ||
598 | |||
599 | static int mipid_spi_remove(struct spi_device *spi) | ||
600 | { | ||
601 | dev_dbg(&spi->dev, "mipid_spi_remove\n"); | ||
602 | omap_dss_unregister_driver(&n8x0_panel_driver); | ||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | static struct spi_driver mipid_spi_driver = { | ||
607 | .driver = { | ||
608 | .name = "lcd_mipid", | ||
609 | .owner = THIS_MODULE, | ||
610 | }, | ||
611 | .probe = mipid_spi_probe, | ||
612 | .remove = mipid_spi_remove, | ||
613 | }; | ||
614 | module_spi_driver(mipid_spi_driver); | ||
615 | |||
616 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c deleted file mode 100644 index 6b9f7925e918..000000000000 --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | /* | ||
2 | * Support for NEC-nl8048hl11-01b panel driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments Inc. | ||
5 | * Author: Erik Gilling <konkers@android.com> | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/spi/spi.h> | ||
22 | #include <linux/fb.h> | ||
23 | #include <linux/gpio.h> | ||
24 | |||
25 | #include <video/omapdss.h> | ||
26 | #include <video/omap-panel-data.h> | ||
27 | |||
28 | #define LCD_XRES 800 | ||
29 | #define LCD_YRES 480 | ||
30 | /* | ||
31 | * NEC PIX Clock Ratings | ||
32 | * MIN:21.8MHz TYP:23.8MHz MAX:25.7MHz | ||
33 | */ | ||
34 | #define LCD_PIXEL_CLOCK 23800 | ||
35 | |||
36 | static const struct { | ||
37 | unsigned char addr; | ||
38 | unsigned char dat; | ||
39 | } nec_8048_init_seq[] = { | ||
40 | { 3, 0x01 }, { 0, 0x00 }, { 1, 0x01 }, { 4, 0x00 }, { 5, 0x14 }, | ||
41 | { 6, 0x24 }, { 16, 0xD7 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x55 }, | ||
42 | { 20, 0x01 }, { 21, 0x70 }, { 22, 0x1E }, { 23, 0x25 }, { 24, 0x25 }, | ||
43 | { 25, 0x02 }, { 26, 0x02 }, { 27, 0xA0 }, { 32, 0x2F }, { 33, 0x0F }, | ||
44 | { 34, 0x0F }, { 35, 0x0F }, { 36, 0x0F }, { 37, 0x0F }, { 38, 0x0F }, | ||
45 | { 39, 0x00 }, { 40, 0x02 }, { 41, 0x02 }, { 42, 0x02 }, { 43, 0x0F }, | ||
46 | { 44, 0x0F }, { 45, 0x0F }, { 46, 0x0F }, { 47, 0x0F }, { 48, 0x0F }, | ||
47 | { 49, 0x0F }, { 50, 0x00 }, { 51, 0x02 }, { 52, 0x02 }, { 53, 0x02 }, | ||
48 | { 80, 0x0C }, { 83, 0x42 }, { 84, 0x42 }, { 85, 0x41 }, { 86, 0x14 }, | ||
49 | { 89, 0x88 }, { 90, 0x01 }, { 91, 0x00 }, { 92, 0x02 }, { 93, 0x0C }, | ||
50 | { 94, 0x1C }, { 95, 0x27 }, { 98, 0x49 }, { 99, 0x27 }, { 102, 0x76 }, | ||
51 | { 103, 0x27 }, { 112, 0x01 }, { 113, 0x0E }, { 114, 0x02 }, | ||
52 | { 115, 0x0C }, { 118, 0x0C }, { 121, 0x30 }, { 130, 0x00 }, | ||
53 | { 131, 0x00 }, { 132, 0xFC }, { 134, 0x00 }, { 136, 0x00 }, | ||
54 | { 138, 0x00 }, { 139, 0x00 }, { 140, 0x00 }, { 141, 0xFC }, | ||
55 | { 143, 0x00 }, { 145, 0x00 }, { 147, 0x00 }, { 148, 0x00 }, | ||
56 | { 149, 0x00 }, { 150, 0xFC }, { 152, 0x00 }, { 154, 0x00 }, | ||
57 | { 156, 0x00 }, { 157, 0x00 }, { 2, 0x00 }, | ||
58 | }; | ||
59 | |||
60 | /* | ||
61 | * NEC NL8048HL11-01B Manual | ||
62 | * defines HFB, HSW, HBP, VFP, VSW, VBP as shown below | ||
63 | */ | ||
64 | |||
65 | static struct omap_video_timings nec_8048_panel_timings = { | ||
66 | /* 800 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ | ||
67 | .x_res = LCD_XRES, | ||
68 | .y_res = LCD_YRES, | ||
69 | .pixel_clock = LCD_PIXEL_CLOCK, | ||
70 | .hfp = 6, | ||
71 | .hsw = 1, | ||
72 | .hbp = 4, | ||
73 | .vfp = 3, | ||
74 | .vsw = 1, | ||
75 | .vbp = 4, | ||
76 | |||
77 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
78 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
79 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
80 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
81 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
82 | }; | ||
83 | |||
84 | static inline struct panel_nec_nl8048_data | ||
85 | *get_panel_data(const struct omap_dss_device *dssdev) | ||
86 | { | ||
87 | return (struct panel_nec_nl8048_data *) dssdev->data; | ||
88 | } | ||
89 | |||
90 | static int nec_8048_panel_probe(struct omap_dss_device *dssdev) | ||
91 | { | ||
92 | struct panel_nec_nl8048_data *pd = get_panel_data(dssdev); | ||
93 | int r; | ||
94 | |||
95 | if (!pd) | ||
96 | return -EINVAL; | ||
97 | |||
98 | dssdev->panel.timings = nec_8048_panel_timings; | ||
99 | |||
100 | if (gpio_is_valid(pd->qvga_gpio)) { | ||
101 | r = devm_gpio_request_one(dssdev->dev, pd->qvga_gpio, | ||
102 | GPIOF_OUT_INIT_HIGH, "lcd QVGA"); | ||
103 | if (r) | ||
104 | return r; | ||
105 | } | ||
106 | |||
107 | if (gpio_is_valid(pd->res_gpio)) { | ||
108 | r = devm_gpio_request_one(dssdev->dev, pd->res_gpio, | ||
109 | GPIOF_OUT_INIT_LOW, "lcd RES"); | ||
110 | if (r) | ||
111 | return r; | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static void nec_8048_panel_remove(struct omap_dss_device *dssdev) | ||
118 | { | ||
119 | } | ||
120 | |||
121 | static int nec_8048_panel_power_on(struct omap_dss_device *dssdev) | ||
122 | { | ||
123 | struct panel_nec_nl8048_data *pd = get_panel_data(dssdev); | ||
124 | int r; | ||
125 | |||
126 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
127 | return 0; | ||
128 | |||
129 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
130 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
131 | |||
132 | r = omapdss_dpi_display_enable(dssdev); | ||
133 | if (r) | ||
134 | goto err0; | ||
135 | |||
136 | if (gpio_is_valid(pd->res_gpio)) | ||
137 | gpio_set_value_cansleep(pd->res_gpio, 1); | ||
138 | |||
139 | return 0; | ||
140 | |||
141 | err0: | ||
142 | return r; | ||
143 | } | ||
144 | |||
145 | static void nec_8048_panel_power_off(struct omap_dss_device *dssdev) | ||
146 | { | ||
147 | struct panel_nec_nl8048_data *pd = get_panel_data(dssdev); | ||
148 | |||
149 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
150 | return; | ||
151 | |||
152 | if (gpio_is_valid(pd->res_gpio)) | ||
153 | gpio_set_value_cansleep(pd->res_gpio, 0); | ||
154 | |||
155 | omapdss_dpi_display_disable(dssdev); | ||
156 | } | ||
157 | |||
158 | static int nec_8048_panel_enable(struct omap_dss_device *dssdev) | ||
159 | { | ||
160 | int r; | ||
161 | |||
162 | r = nec_8048_panel_power_on(dssdev); | ||
163 | if (r) | ||
164 | return r; | ||
165 | |||
166 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static void nec_8048_panel_disable(struct omap_dss_device *dssdev) | ||
172 | { | ||
173 | nec_8048_panel_power_off(dssdev); | ||
174 | |||
175 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
176 | } | ||
177 | |||
178 | static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev) | ||
179 | { | ||
180 | return 16; | ||
181 | } | ||
182 | |||
183 | static struct omap_dss_driver nec_8048_driver = { | ||
184 | .probe = nec_8048_panel_probe, | ||
185 | .remove = nec_8048_panel_remove, | ||
186 | .enable = nec_8048_panel_enable, | ||
187 | .disable = nec_8048_panel_disable, | ||
188 | .get_recommended_bpp = nec_8048_recommended_bpp, | ||
189 | |||
190 | .driver = { | ||
191 | .name = "NEC_8048_panel", | ||
192 | .owner = THIS_MODULE, | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | static int nec_8048_spi_send(struct spi_device *spi, unsigned char reg_addr, | ||
197 | unsigned char reg_data) | ||
198 | { | ||
199 | int ret = 0; | ||
200 | unsigned int cmd = 0, data = 0; | ||
201 | |||
202 | cmd = 0x0000 | reg_addr; /* register address write */ | ||
203 | data = 0x0100 | reg_data ; /* register data write */ | ||
204 | data = (cmd << 16) | data; | ||
205 | |||
206 | ret = spi_write(spi, (unsigned char *)&data, 4); | ||
207 | if (ret) | ||
208 | pr_err("error in spi_write %x\n", data); | ||
209 | |||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | static int init_nec_8048_wvga_lcd(struct spi_device *spi) | ||
214 | { | ||
215 | unsigned int i; | ||
216 | /* Initialization Sequence */ | ||
217 | /* nec_8048_spi_send(spi, REG, VAL) */ | ||
218 | for (i = 0; i < (ARRAY_SIZE(nec_8048_init_seq) - 1); i++) | ||
219 | nec_8048_spi_send(spi, nec_8048_init_seq[i].addr, | ||
220 | nec_8048_init_seq[i].dat); | ||
221 | udelay(20); | ||
222 | nec_8048_spi_send(spi, nec_8048_init_seq[i].addr, | ||
223 | nec_8048_init_seq[i].dat); | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int nec_8048_spi_probe(struct spi_device *spi) | ||
228 | { | ||
229 | spi->mode = SPI_MODE_0; | ||
230 | spi->bits_per_word = 32; | ||
231 | spi_setup(spi); | ||
232 | |||
233 | init_nec_8048_wvga_lcd(spi); | ||
234 | |||
235 | return omap_dss_register_driver(&nec_8048_driver); | ||
236 | } | ||
237 | |||
238 | static int nec_8048_spi_remove(struct spi_device *spi) | ||
239 | { | ||
240 | omap_dss_unregister_driver(&nec_8048_driver); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | #ifdef CONFIG_PM_SLEEP | ||
246 | |||
247 | static int nec_8048_spi_suspend(struct device *dev) | ||
248 | { | ||
249 | struct spi_device *spi = to_spi_device(dev); | ||
250 | |||
251 | nec_8048_spi_send(spi, 2, 0x01); | ||
252 | mdelay(40); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static int nec_8048_spi_resume(struct device *dev) | ||
258 | { | ||
259 | struct spi_device *spi = to_spi_device(dev); | ||
260 | |||
261 | /* reinitialize the panel */ | ||
262 | spi_setup(spi); | ||
263 | nec_8048_spi_send(spi, 2, 0x00); | ||
264 | init_nec_8048_wvga_lcd(spi); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static SIMPLE_DEV_PM_OPS(nec_8048_spi_pm_ops, nec_8048_spi_suspend, | ||
270 | nec_8048_spi_resume); | ||
271 | #define NEC_8048_SPI_PM_OPS (&nec_8048_spi_pm_ops) | ||
272 | #else | ||
273 | #define NEC_8048_SPI_PM_OPS NULL | ||
274 | #endif | ||
275 | |||
276 | static struct spi_driver nec_8048_spi_driver = { | ||
277 | .probe = nec_8048_spi_probe, | ||
278 | .remove = nec_8048_spi_remove, | ||
279 | .driver = { | ||
280 | .name = "nec_8048_spi", | ||
281 | .owner = THIS_MODULE, | ||
282 | .pm = NEC_8048_SPI_PM_OPS, | ||
283 | }, | ||
284 | }; | ||
285 | |||
286 | module_spi_driver(nec_8048_spi_driver); | ||
287 | |||
288 | MODULE_AUTHOR("Erik Gilling <konkers@android.com>"); | ||
289 | MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver"); | ||
290 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c deleted file mode 100644 index 153e9bea0f6e..000000000000 --- a/drivers/video/omap2/displays/panel-picodlp.c +++ /dev/null | |||
@@ -1,559 +0,0 @@ | |||
1 | /* | ||
2 | * picodlp panel driver | ||
3 | * picodlp_i2c_driver: i2c_client driver | ||
4 | * | ||
5 | * Copyright (C) 2009-2011 Texas Instruments | ||
6 | * Author: Mythri P K <mythripk@ti.com> | ||
7 | * Mayuresh Janorkar <mayur@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License version 2 as published by | ||
11 | * the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/firmware.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/gpio.h> | ||
32 | |||
33 | #include <video/omapdss.h> | ||
34 | #include <video/omap-panel-data.h> | ||
35 | |||
36 | #include "panel-picodlp.h" | ||
37 | |||
38 | struct picodlp_data { | ||
39 | struct mutex lock; | ||
40 | struct i2c_client *picodlp_i2c_client; | ||
41 | }; | ||
42 | |||
43 | static struct i2c_board_info picodlp_i2c_board_info = { | ||
44 | I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b), | ||
45 | }; | ||
46 | |||
47 | struct picodlp_i2c_data { | ||
48 | struct mutex xfer_lock; | ||
49 | }; | ||
50 | |||
51 | static struct i2c_device_id picodlp_i2c_id[] = { | ||
52 | { "picodlp_i2c_driver", 0 }, | ||
53 | { } | ||
54 | }; | ||
55 | |||
56 | struct picodlp_i2c_command { | ||
57 | u8 reg; | ||
58 | u32 value; | ||
59 | }; | ||
60 | |||
61 | static struct omap_video_timings pico_ls_timings = { | ||
62 | .x_res = 864, | ||
63 | .y_res = 480, | ||
64 | .hsw = 7, | ||
65 | .hfp = 11, | ||
66 | .hbp = 7, | ||
67 | |||
68 | .pixel_clock = 19200, | ||
69 | |||
70 | .vsw = 2, | ||
71 | .vfp = 3, | ||
72 | .vbp = 14, | ||
73 | |||
74 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
75 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
76 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
77 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
78 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
79 | }; | ||
80 | |||
81 | static inline struct picodlp_panel_data | ||
82 | *get_panel_data(const struct omap_dss_device *dssdev) | ||
83 | { | ||
84 | return (struct picodlp_panel_data *) dssdev->data; | ||
85 | } | ||
86 | |||
87 | static u32 picodlp_i2c_read(struct i2c_client *client, u8 reg) | ||
88 | { | ||
89 | u8 read_cmd[] = {READ_REG_SELECT, reg}, data[4]; | ||
90 | struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client); | ||
91 | struct i2c_msg msg[2]; | ||
92 | |||
93 | mutex_lock(&picodlp_i2c_data->xfer_lock); | ||
94 | |||
95 | msg[0].addr = client->addr; | ||
96 | msg[0].flags = 0; | ||
97 | msg[0].len = 2; | ||
98 | msg[0].buf = read_cmd; | ||
99 | |||
100 | msg[1].addr = client->addr; | ||
101 | msg[1].flags = I2C_M_RD; | ||
102 | msg[1].len = 4; | ||
103 | msg[1].buf = data; | ||
104 | |||
105 | i2c_transfer(client->adapter, msg, 2); | ||
106 | mutex_unlock(&picodlp_i2c_data->xfer_lock); | ||
107 | return (data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24)); | ||
108 | } | ||
109 | |||
110 | static int picodlp_i2c_write_block(struct i2c_client *client, | ||
111 | u8 *data, int len) | ||
112 | { | ||
113 | struct i2c_msg msg; | ||
114 | int i, r, msg_count = 1; | ||
115 | |||
116 | struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client); | ||
117 | |||
118 | if (len < 1 || len > 32) { | ||
119 | dev_err(&client->dev, | ||
120 | "too long syn_write_block len %d\n", len); | ||
121 | return -EIO; | ||
122 | } | ||
123 | mutex_lock(&picodlp_i2c_data->xfer_lock); | ||
124 | |||
125 | msg.addr = client->addr; | ||
126 | msg.flags = 0; | ||
127 | msg.len = len; | ||
128 | msg.buf = data; | ||
129 | r = i2c_transfer(client->adapter, &msg, msg_count); | ||
130 | mutex_unlock(&picodlp_i2c_data->xfer_lock); | ||
131 | |||
132 | /* | ||
133 | * i2c_transfer returns: | ||
134 | * number of messages sent in case of success | ||
135 | * a negative error number in case of failure | ||
136 | */ | ||
137 | if (r != msg_count) | ||
138 | goto err; | ||
139 | |||
140 | /* In case of success */ | ||
141 | for (i = 0; i < len; i++) | ||
142 | dev_dbg(&client->dev, | ||
143 | "addr %x bw 0x%02x[%d]: 0x%02x\n", | ||
144 | client->addr, data[0] + i, i, data[i]); | ||
145 | |||
146 | return 0; | ||
147 | err: | ||
148 | dev_err(&client->dev, "picodlp_i2c_write error\n"); | ||
149 | return r; | ||
150 | } | ||
151 | |||
152 | static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value) | ||
153 | { | ||
154 | u8 data[5]; | ||
155 | int i; | ||
156 | |||
157 | data[0] = reg; | ||
158 | for (i = 1; i < 5; i++) | ||
159 | data[i] = (value >> (32 - (i) * 8)) & 0xFF; | ||
160 | |||
161 | return picodlp_i2c_write_block(client, data, 5); | ||
162 | } | ||
163 | |||
164 | static int picodlp_i2c_write_array(struct i2c_client *client, | ||
165 | const struct picodlp_i2c_command commands[], | ||
166 | int count) | ||
167 | { | ||
168 | int i, r = 0; | ||
169 | for (i = 0; i < count; i++) { | ||
170 | r = picodlp_i2c_write(client, commands[i].reg, | ||
171 | commands[i].value); | ||
172 | if (r) | ||
173 | return r; | ||
174 | } | ||
175 | return r; | ||
176 | } | ||
177 | |||
178 | static int picodlp_wait_for_dma_done(struct i2c_client *client) | ||
179 | { | ||
180 | u8 trial = 100; | ||
181 | |||
182 | do { | ||
183 | msleep(1); | ||
184 | if (!trial--) | ||
185 | return -ETIMEDOUT; | ||
186 | } while (picodlp_i2c_read(client, MAIN_STATUS) & DMA_STATUS); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * picodlp_i2c_init: i2c_initialization routine | ||
193 | * client: i2c_client for communication | ||
194 | * | ||
195 | * return | ||
196 | * 0 : Success, no error | ||
197 | * error code : Failure | ||
198 | */ | ||
199 | static int picodlp_i2c_init(struct i2c_client *client) | ||
200 | { | ||
201 | int r; | ||
202 | static const struct picodlp_i2c_command init_cmd_set1[] = { | ||
203 | {SOFT_RESET, 1}, | ||
204 | {DMD_PARK_TRIGGER, 1}, | ||
205 | {MISC_REG, 5}, | ||
206 | {SEQ_CONTROL, 0}, | ||
207 | {SEQ_VECTOR, 0x100}, | ||
208 | {DMD_BLOCK_COUNT, 7}, | ||
209 | {DMD_VCC_CONTROL, 0x109}, | ||
210 | {DMD_PARK_PULSE_COUNT, 0xA}, | ||
211 | {DMD_PARK_PULSE_WIDTH, 0xB}, | ||
212 | {DMD_PARK_DELAY, 0x2ED}, | ||
213 | {DMD_SHADOW_ENABLE, 0}, | ||
214 | {FLASH_OPCODE, 0xB}, | ||
215 | {FLASH_DUMMY_BYTES, 1}, | ||
216 | {FLASH_ADDR_BYTES, 3}, | ||
217 | {PBC_CONTROL, 0}, | ||
218 | {FLASH_START_ADDR, CMT_LUT_0_START_ADDR}, | ||
219 | {FLASH_READ_BYTES, CMT_LUT_0_SIZE}, | ||
220 | {CMT_SPLASH_LUT_START_ADDR, 0}, | ||
221 | {CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL}, | ||
222 | {PBC_CONTROL, 1}, | ||
223 | }; | ||
224 | |||
225 | static const struct picodlp_i2c_command init_cmd_set2[] = { | ||
226 | {PBC_CONTROL, 0}, | ||
227 | {CMT_SPLASH_LUT_DEST_SELECT, 0}, | ||
228 | {PBC_CONTROL, 0}, | ||
229 | {FLASH_START_ADDR, SEQUENCE_0_START_ADDR}, | ||
230 | {FLASH_READ_BYTES, SEQUENCE_0_SIZE}, | ||
231 | {SEQ_RESET_LUT_START_ADDR, 0}, | ||
232 | {SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT}, | ||
233 | {PBC_CONTROL, 1}, | ||
234 | }; | ||
235 | |||
236 | static const struct picodlp_i2c_command init_cmd_set3[] = { | ||
237 | {PBC_CONTROL, 0}, | ||
238 | {SEQ_RESET_LUT_DEST_SELECT, 0}, | ||
239 | {PBC_CONTROL, 0}, | ||
240 | {FLASH_START_ADDR, DRC_TABLE_0_START_ADDR}, | ||
241 | {FLASH_READ_BYTES, DRC_TABLE_0_SIZE}, | ||
242 | {SEQ_RESET_LUT_START_ADDR, 0}, | ||
243 | {SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL}, | ||
244 | {PBC_CONTROL, 1}, | ||
245 | }; | ||
246 | |||
247 | static const struct picodlp_i2c_command init_cmd_set4[] = { | ||
248 | {PBC_CONTROL, 0}, | ||
249 | {SEQ_RESET_LUT_DEST_SELECT, 0}, | ||
250 | {SDC_ENABLE, 1}, | ||
251 | {AGC_CTRL, 7}, | ||
252 | {CCA_C1A, 0x100}, | ||
253 | {CCA_C1B, 0x0}, | ||
254 | {CCA_C1C, 0x0}, | ||
255 | {CCA_C2A, 0x0}, | ||
256 | {CCA_C2B, 0x100}, | ||
257 | {CCA_C2C, 0x0}, | ||
258 | {CCA_C3A, 0x0}, | ||
259 | {CCA_C3B, 0x0}, | ||
260 | {CCA_C3C, 0x100}, | ||
261 | {CCA_C7A, 0x100}, | ||
262 | {CCA_C7B, 0x100}, | ||
263 | {CCA_C7C, 0x100}, | ||
264 | {CCA_ENABLE, 1}, | ||
265 | {CPU_IF_MODE, 1}, | ||
266 | {SHORT_FLIP, 1}, | ||
267 | {CURTAIN_CONTROL, 0}, | ||
268 | {DMD_PARK_TRIGGER, 0}, | ||
269 | {R_DRIVE_CURRENT, 0x298}, | ||
270 | {G_DRIVE_CURRENT, 0x298}, | ||
271 | {B_DRIVE_CURRENT, 0x298}, | ||
272 | {RGB_DRIVER_ENABLE, 7}, | ||
273 | {SEQ_CONTROL, 0}, | ||
274 | {ACTGEN_CONTROL, 0x10}, | ||
275 | {SEQUENCE_MODE, SEQ_LOCK}, | ||
276 | {DATA_FORMAT, RGB888}, | ||
277 | {INPUT_RESOLUTION, WVGA_864_LANDSCAPE}, | ||
278 | {INPUT_SOURCE, PARALLEL_RGB}, | ||
279 | {CPU_IF_SYNC_METHOD, 1}, | ||
280 | {SEQ_CONTROL, 1} | ||
281 | }; | ||
282 | |||
283 | r = picodlp_i2c_write_array(client, init_cmd_set1, | ||
284 | ARRAY_SIZE(init_cmd_set1)); | ||
285 | if (r) | ||
286 | return r; | ||
287 | |||
288 | r = picodlp_wait_for_dma_done(client); | ||
289 | if (r) | ||
290 | return r; | ||
291 | |||
292 | r = picodlp_i2c_write_array(client, init_cmd_set2, | ||
293 | ARRAY_SIZE(init_cmd_set2)); | ||
294 | if (r) | ||
295 | return r; | ||
296 | |||
297 | r = picodlp_wait_for_dma_done(client); | ||
298 | if (r) | ||
299 | return r; | ||
300 | |||
301 | r = picodlp_i2c_write_array(client, init_cmd_set3, | ||
302 | ARRAY_SIZE(init_cmd_set3)); | ||
303 | if (r) | ||
304 | return r; | ||
305 | |||
306 | r = picodlp_wait_for_dma_done(client); | ||
307 | if (r) | ||
308 | return r; | ||
309 | |||
310 | r = picodlp_i2c_write_array(client, init_cmd_set4, | ||
311 | ARRAY_SIZE(init_cmd_set4)); | ||
312 | if (r) | ||
313 | return r; | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int picodlp_i2c_probe(struct i2c_client *client, | ||
319 | const struct i2c_device_id *id) | ||
320 | { | ||
321 | struct picodlp_i2c_data *picodlp_i2c_data; | ||
322 | |||
323 | picodlp_i2c_data = kzalloc(sizeof(struct picodlp_i2c_data), GFP_KERNEL); | ||
324 | |||
325 | if (!picodlp_i2c_data) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | mutex_init(&picodlp_i2c_data->xfer_lock); | ||
329 | i2c_set_clientdata(client, picodlp_i2c_data); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static int picodlp_i2c_remove(struct i2c_client *client) | ||
335 | { | ||
336 | struct picodlp_i2c_data *picodlp_i2c_data = | ||
337 | i2c_get_clientdata(client); | ||
338 | kfree(picodlp_i2c_data); | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static struct i2c_driver picodlp_i2c_driver = { | ||
343 | .driver = { | ||
344 | .name = "picodlp_i2c_driver", | ||
345 | }, | ||
346 | .probe = picodlp_i2c_probe, | ||
347 | .remove = picodlp_i2c_remove, | ||
348 | .id_table = picodlp_i2c_id, | ||
349 | }; | ||
350 | |||
351 | static int picodlp_panel_power_on(struct omap_dss_device *dssdev) | ||
352 | { | ||
353 | int r, trial = 100; | ||
354 | struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); | ||
355 | struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); | ||
356 | |||
357 | gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); | ||
358 | msleep(1); | ||
359 | gpio_set_value(picodlp_pdata->pwrgood_gpio, 1); | ||
360 | |||
361 | while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) { | ||
362 | if (!trial--) { | ||
363 | dev_err(dssdev->dev, "emu_done signal not" | ||
364 | " going high\n"); | ||
365 | return -ETIMEDOUT; | ||
366 | } | ||
367 | msleep(5); | ||
368 | } | ||
369 | /* | ||
370 | * As per dpp2600 programming guide, | ||
371 | * it is required to sleep for 1000ms after emu_done signal goes high | ||
372 | * then only i2c commands can be successfully sent to dpp2600 | ||
373 | */ | ||
374 | msleep(1000); | ||
375 | |||
376 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
377 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
378 | |||
379 | r = omapdss_dpi_display_enable(dssdev); | ||
380 | if (r) { | ||
381 | dev_err(dssdev->dev, "failed to enable DPI\n"); | ||
382 | goto err1; | ||
383 | } | ||
384 | |||
385 | r = picodlp_i2c_init(picod->picodlp_i2c_client); | ||
386 | if (r) | ||
387 | goto err; | ||
388 | |||
389 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
390 | |||
391 | return r; | ||
392 | err: | ||
393 | omapdss_dpi_display_disable(dssdev); | ||
394 | err1: | ||
395 | return r; | ||
396 | } | ||
397 | |||
398 | static void picodlp_panel_power_off(struct omap_dss_device *dssdev) | ||
399 | { | ||
400 | struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); | ||
401 | |||
402 | omapdss_dpi_display_disable(dssdev); | ||
403 | |||
404 | gpio_set_value(picodlp_pdata->emu_done_gpio, 0); | ||
405 | gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); | ||
406 | } | ||
407 | |||
408 | static int picodlp_panel_probe(struct omap_dss_device *dssdev) | ||
409 | { | ||
410 | struct picodlp_data *picod; | ||
411 | struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); | ||
412 | struct i2c_adapter *adapter; | ||
413 | struct i2c_client *picodlp_i2c_client; | ||
414 | int r, picodlp_adapter_id; | ||
415 | |||
416 | dssdev->panel.timings = pico_ls_timings; | ||
417 | |||
418 | if (!picodlp_pdata) | ||
419 | return -EINVAL; | ||
420 | |||
421 | picod = devm_kzalloc(dssdev->dev, sizeof(*picod), GFP_KERNEL); | ||
422 | if (!picod) | ||
423 | return -ENOMEM; | ||
424 | |||
425 | mutex_init(&picod->lock); | ||
426 | |||
427 | picodlp_adapter_id = picodlp_pdata->picodlp_adapter_id; | ||
428 | |||
429 | adapter = i2c_get_adapter(picodlp_adapter_id); | ||
430 | if (!adapter) { | ||
431 | dev_err(dssdev->dev, "can't get i2c adapter\n"); | ||
432 | return -ENODEV; | ||
433 | } | ||
434 | |||
435 | picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info); | ||
436 | if (!picodlp_i2c_client) { | ||
437 | dev_err(dssdev->dev, "can't add i2c device::" | ||
438 | " picodlp_i2c_client is NULL\n"); | ||
439 | return -ENODEV; | ||
440 | } | ||
441 | |||
442 | picod->picodlp_i2c_client = picodlp_i2c_client; | ||
443 | |||
444 | dev_set_drvdata(dssdev->dev, picod); | ||
445 | |||
446 | if (gpio_is_valid(picodlp_pdata->emu_done_gpio)) { | ||
447 | r = devm_gpio_request_one(dssdev->dev, | ||
448 | picodlp_pdata->emu_done_gpio, | ||
449 | GPIOF_IN, "DLP EMU DONE"); | ||
450 | if (r) | ||
451 | return r; | ||
452 | } | ||
453 | |||
454 | if (gpio_is_valid(picodlp_pdata->pwrgood_gpio)) { | ||
455 | r = devm_gpio_request_one(dssdev->dev, | ||
456 | picodlp_pdata->pwrgood_gpio, | ||
457 | GPIOF_OUT_INIT_LOW, "DLP PWRGOOD"); | ||
458 | if (r) | ||
459 | return r; | ||
460 | } | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static void picodlp_panel_remove(struct omap_dss_device *dssdev) | ||
466 | { | ||
467 | struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); | ||
468 | |||
469 | i2c_unregister_device(picod->picodlp_i2c_client); | ||
470 | dev_set_drvdata(dssdev->dev, NULL); | ||
471 | dev_dbg(dssdev->dev, "removing picodlp panel\n"); | ||
472 | } | ||
473 | |||
474 | static int picodlp_panel_enable(struct omap_dss_device *dssdev) | ||
475 | { | ||
476 | struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); | ||
477 | int r; | ||
478 | |||
479 | dev_dbg(dssdev->dev, "enabling picodlp panel\n"); | ||
480 | |||
481 | mutex_lock(&picod->lock); | ||
482 | if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { | ||
483 | mutex_unlock(&picod->lock); | ||
484 | return -EINVAL; | ||
485 | } | ||
486 | |||
487 | r = picodlp_panel_power_on(dssdev); | ||
488 | mutex_unlock(&picod->lock); | ||
489 | |||
490 | return r; | ||
491 | } | ||
492 | |||
493 | static void picodlp_panel_disable(struct omap_dss_device *dssdev) | ||
494 | { | ||
495 | struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); | ||
496 | |||
497 | mutex_lock(&picod->lock); | ||
498 | /* Turn off DLP Power */ | ||
499 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
500 | picodlp_panel_power_off(dssdev); | ||
501 | |||
502 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
503 | mutex_unlock(&picod->lock); | ||
504 | |||
505 | dev_dbg(dssdev->dev, "disabling picodlp panel\n"); | ||
506 | } | ||
507 | |||
508 | static void picodlp_get_resolution(struct omap_dss_device *dssdev, | ||
509 | u16 *xres, u16 *yres) | ||
510 | { | ||
511 | *xres = dssdev->panel.timings.x_res; | ||
512 | *yres = dssdev->panel.timings.y_res; | ||
513 | } | ||
514 | |||
515 | static struct omap_dss_driver picodlp_driver = { | ||
516 | .probe = picodlp_panel_probe, | ||
517 | .remove = picodlp_panel_remove, | ||
518 | |||
519 | .enable = picodlp_panel_enable, | ||
520 | .disable = picodlp_panel_disable, | ||
521 | |||
522 | .get_resolution = picodlp_get_resolution, | ||
523 | |||
524 | .driver = { | ||
525 | .name = "picodlp_panel", | ||
526 | .owner = THIS_MODULE, | ||
527 | }, | ||
528 | }; | ||
529 | |||
530 | static int __init picodlp_init(void) | ||
531 | { | ||
532 | int r = 0; | ||
533 | |||
534 | r = i2c_add_driver(&picodlp_i2c_driver); | ||
535 | if (r) { | ||
536 | printk(KERN_WARNING "picodlp_i2c_driver" \ | ||
537 | " registration failed\n"); | ||
538 | return r; | ||
539 | } | ||
540 | |||
541 | r = omap_dss_register_driver(&picodlp_driver); | ||
542 | if (r) | ||
543 | i2c_del_driver(&picodlp_i2c_driver); | ||
544 | |||
545 | return r; | ||
546 | } | ||
547 | |||
548 | static void __exit picodlp_exit(void) | ||
549 | { | ||
550 | i2c_del_driver(&picodlp_i2c_driver); | ||
551 | omap_dss_unregister_driver(&picodlp_driver); | ||
552 | } | ||
553 | |||
554 | module_init(picodlp_init); | ||
555 | module_exit(picodlp_exit); | ||
556 | |||
557 | MODULE_AUTHOR("Mythri P K <mythripk@ti.com>"); | ||
558 | MODULE_DESCRIPTION("picodlp driver"); | ||
559 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-picodlp.h b/drivers/video/omap2/displays/panel-picodlp.h deleted file mode 100644 index a34b431a7267..000000000000 --- a/drivers/video/omap2/displays/panel-picodlp.h +++ /dev/null | |||
@@ -1,288 +0,0 @@ | |||
1 | /* | ||
2 | * Header file required by picodlp panel driver | ||
3 | * | ||
4 | * Copyright (C) 2009-2011 Texas Instruments | ||
5 | * Author: Mythri P K <mythripk@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #ifndef __OMAP2_DISPLAY_PANEL_PICODLP_H | ||
21 | #define __OMAP2_DISPLAY_PANEL_PICODLP_H | ||
22 | |||
23 | /* Commands used for configuring picodlp panel */ | ||
24 | |||
25 | #define MAIN_STATUS 0x03 | ||
26 | #define PBC_CONTROL 0x08 | ||
27 | #define INPUT_SOURCE 0x0B | ||
28 | #define INPUT_RESOLUTION 0x0C | ||
29 | #define DATA_FORMAT 0x0D | ||
30 | #define IMG_ROTATION 0x0E | ||
31 | #define LONG_FLIP 0x0F | ||
32 | #define SHORT_FLIP 0x10 | ||
33 | #define TEST_PAT_SELECT 0x11 | ||
34 | #define R_DRIVE_CURRENT 0x12 | ||
35 | #define G_DRIVE_CURRENT 0x13 | ||
36 | #define B_DRIVE_CURRENT 0x14 | ||
37 | #define READ_REG_SELECT 0x15 | ||
38 | #define RGB_DRIVER_ENABLE 0x16 | ||
39 | |||
40 | #define CPU_IF_MODE 0x18 | ||
41 | #define FRAME_RATE 0x19 | ||
42 | #define CPU_IF_SYNC_METHOD 0x1A | ||
43 | #define CPU_IF_SOF 0x1B | ||
44 | #define CPU_IF_EOF 0x1C | ||
45 | #define CPU_IF_SLEEP 0x1D | ||
46 | |||
47 | #define SEQUENCE_MODE 0x1E | ||
48 | #define SOFT_RESET 0x1F | ||
49 | #define FRONT_END_RESET 0x21 | ||
50 | #define AUTO_PWR_ENABLE 0x22 | ||
51 | |||
52 | #define VSYNC_LINE_DELAY 0x23 | ||
53 | #define CPU_PI_HORIZ_START 0x24 | ||
54 | #define CPU_PI_VERT_START 0x25 | ||
55 | #define CPU_PI_HORIZ_WIDTH 0x26 | ||
56 | #define CPU_PI_VERT_HEIGHT 0x27 | ||
57 | |||
58 | #define PIXEL_MASK_CROP 0x28 | ||
59 | #define CROP_FIRST_LINE 0x29 | ||
60 | #define CROP_LAST_LINE 0x2A | ||
61 | #define CROP_FIRST_PIXEL 0x2B | ||
62 | #define CROP_LAST_PIXEL 0x2C | ||
63 | #define DMD_PARK_TRIGGER 0x2D | ||
64 | |||
65 | #define MISC_REG 0x30 | ||
66 | |||
67 | /* AGC registers */ | ||
68 | #define AGC_CTRL 0x50 | ||
69 | #define AGC_CLIPPED_PIXS 0x55 | ||
70 | #define AGC_BRIGHT_PIXS 0x56 | ||
71 | #define AGC_BG_PIXS 0x57 | ||
72 | #define AGC_SAFETY_MARGIN 0x17 | ||
73 | |||
74 | /* Color Coordinate Adjustment registers */ | ||
75 | #define CCA_ENABLE 0x5E | ||
76 | #define CCA_C1A 0x5F | ||
77 | #define CCA_C1B 0x60 | ||
78 | #define CCA_C1C 0x61 | ||
79 | #define CCA_C2A 0x62 | ||
80 | #define CCA_C2B 0x63 | ||
81 | #define CCA_C2C 0x64 | ||
82 | #define CCA_C3A 0x65 | ||
83 | #define CCA_C3B 0x66 | ||
84 | #define CCA_C3C 0x67 | ||
85 | #define CCA_C7A 0x71 | ||
86 | #define CCA_C7B 0x72 | ||
87 | #define CCA_C7C 0x73 | ||
88 | |||
89 | /** | ||
90 | * DLP Pico Processor 2600 comes with flash | ||
91 | * We can do DMA operations from flash for accessing Look Up Tables | ||
92 | */ | ||
93 | #define DMA_STATUS 0x100 | ||
94 | #define FLASH_ADDR_BYTES 0x74 | ||
95 | #define FLASH_DUMMY_BYTES 0x75 | ||
96 | #define FLASH_WRITE_BYTES 0x76 | ||
97 | #define FLASH_READ_BYTES 0x77 | ||
98 | #define FLASH_OPCODE 0x78 | ||
99 | #define FLASH_START_ADDR 0x79 | ||
100 | #define FLASH_DUMMY2 0x7A | ||
101 | #define FLASH_WRITE_DATA 0x7B | ||
102 | |||
103 | #define TEMPORAL_DITH_DISABLE 0x7E | ||
104 | #define SEQ_CONTROL 0x82 | ||
105 | #define SEQ_VECTOR 0x83 | ||
106 | |||
107 | /* DMD is Digital Micromirror Device */ | ||
108 | #define DMD_BLOCK_COUNT 0x84 | ||
109 | #define DMD_VCC_CONTROL 0x86 | ||
110 | #define DMD_PARK_PULSE_COUNT 0x87 | ||
111 | #define DMD_PARK_PULSE_WIDTH 0x88 | ||
112 | #define DMD_PARK_DELAY 0x89 | ||
113 | #define DMD_SHADOW_ENABLE 0x8E | ||
114 | #define SEQ_STATUS 0x8F | ||
115 | #define FLASH_CLOCK_CONTROL 0x98 | ||
116 | #define DMD_PARK 0x2D | ||
117 | |||
118 | #define SDRAM_BIST_ENABLE 0x46 | ||
119 | #define DDR_DRIVER_STRENGTH 0x9A | ||
120 | #define SDC_ENABLE 0x9D | ||
121 | #define SDC_BUFF_SWAP_DISABLE 0xA3 | ||
122 | #define CURTAIN_CONTROL 0xA6 | ||
123 | #define DDR_BUS_SWAP_ENABLE 0xA7 | ||
124 | #define DMD_TRC_ENABLE 0xA8 | ||
125 | #define DMD_BUS_SWAP_ENABLE 0xA9 | ||
126 | |||
127 | #define ACTGEN_ENABLE 0xAE | ||
128 | #define ACTGEN_CONTROL 0xAF | ||
129 | #define ACTGEN_HORIZ_BP 0xB0 | ||
130 | #define ACTGEN_VERT_BP 0xB1 | ||
131 | |||
132 | /* Look Up Table access */ | ||
133 | #define CMT_SPLASH_LUT_START_ADDR 0xFA | ||
134 | #define CMT_SPLASH_LUT_DEST_SELECT 0xFB | ||
135 | #define CMT_SPLASH_LUT_DATA 0xFC | ||
136 | #define SEQ_RESET_LUT_START_ADDR 0xFD | ||
137 | #define SEQ_RESET_LUT_DEST_SELECT 0xFE | ||
138 | #define SEQ_RESET_LUT_DATA 0xFF | ||
139 | |||
140 | /* Input source definitions */ | ||
141 | #define PARALLEL_RGB 0 | ||
142 | #define INT_TEST_PATTERN 1 | ||
143 | #define SPLASH_SCREEN 2 | ||
144 | #define CPU_INTF 3 | ||
145 | #define BT656 4 | ||
146 | |||
147 | /* Standard input resolution definitions */ | ||
148 | #define QWVGA_LANDSCAPE 3 /* (427h*240v) */ | ||
149 | #define WVGA_864_LANDSCAPE 21 /* (864h*480v) */ | ||
150 | #define WVGA_DMD_OPTICAL_TEST 35 /* (608h*684v) */ | ||
151 | |||
152 | /* Standard data format definitions */ | ||
153 | #define RGB565 0 | ||
154 | #define RGB666 1 | ||
155 | #define RGB888 2 | ||
156 | |||
157 | /* Test Pattern definitions */ | ||
158 | #define TPG_CHECKERBOARD 0 | ||
159 | #define TPG_BLACK 1 | ||
160 | #define TPG_WHITE 2 | ||
161 | #define TPG_RED 3 | ||
162 | #define TPG_BLUE 4 | ||
163 | #define TPG_GREEN 5 | ||
164 | #define TPG_VLINES_BLACK 6 | ||
165 | #define TPG_HLINES_BLACK 7 | ||
166 | #define TPG_VLINES_ALT 8 | ||
167 | #define TPG_HLINES_ALT 9 | ||
168 | #define TPG_DIAG_LINES 10 | ||
169 | #define TPG_GREYRAMP_VERT 11 | ||
170 | #define TPG_GREYRAMP_HORIZ 12 | ||
171 | #define TPG_ANSI_CHECKERBOARD 13 | ||
172 | |||
173 | /* sequence mode definitions */ | ||
174 | #define SEQ_FREE_RUN 0 | ||
175 | #define SEQ_LOCK 1 | ||
176 | |||
177 | /* curtain color definitions */ | ||
178 | #define CURTAIN_BLACK 0 | ||
179 | #define CURTAIN_RED 1 | ||
180 | #define CURTAIN_GREEN 2 | ||
181 | #define CURTAIN_BLUE 3 | ||
182 | #define CURTAIN_YELLOW 4 | ||
183 | #define CURTAIN_MAGENTA 5 | ||
184 | #define CURTAIN_CYAN 6 | ||
185 | #define CURTAIN_WHITE 7 | ||
186 | |||
187 | /* LUT definitions */ | ||
188 | #define CMT_LUT_NONE 0 | ||
189 | #define CMT_LUT_GREEN 1 | ||
190 | #define CMT_LUT_RED 2 | ||
191 | #define CMT_LUT_BLUE 3 | ||
192 | #define CMT_LUT_ALL 4 | ||
193 | #define SPLASH_LUT 5 | ||
194 | |||
195 | #define SEQ_LUT_NONE 0 | ||
196 | #define SEQ_DRC_LUT_0 1 | ||
197 | #define SEQ_DRC_LUT_1 2 | ||
198 | #define SEQ_DRC_LUT_2 3 | ||
199 | #define SEQ_DRC_LUT_3 4 | ||
200 | #define SEQ_SEQ_LUT 5 | ||
201 | #define SEQ_DRC_LUT_ALL 6 | ||
202 | #define WPC_PROGRAM_LUT 7 | ||
203 | |||
204 | #define BITSTREAM_START_ADDR 0x00000000 | ||
205 | #define BITSTREAM_SIZE 0x00040000 | ||
206 | |||
207 | #define WPC_FW_0_START_ADDR 0x00040000 | ||
208 | #define WPC_FW_0_SIZE 0x00000ce8 | ||
209 | |||
210 | #define SEQUENCE_0_START_ADDR 0x00044000 | ||
211 | #define SEQUENCE_0_SIZE 0x00001000 | ||
212 | |||
213 | #define SEQUENCE_1_START_ADDR 0x00045000 | ||
214 | #define SEQUENCE_1_SIZE 0x00000d10 | ||
215 | |||
216 | #define SEQUENCE_2_START_ADDR 0x00046000 | ||
217 | #define SEQUENCE_2_SIZE 0x00000d10 | ||
218 | |||
219 | #define SEQUENCE_3_START_ADDR 0x00047000 | ||
220 | #define SEQUENCE_3_SIZE 0x00000d10 | ||
221 | |||
222 | #define SEQUENCE_4_START_ADDR 0x00048000 | ||
223 | #define SEQUENCE_4_SIZE 0x00000d10 | ||
224 | |||
225 | #define SEQUENCE_5_START_ADDR 0x00049000 | ||
226 | #define SEQUENCE_5_SIZE 0x00000d10 | ||
227 | |||
228 | #define SEQUENCE_6_START_ADDR 0x0004a000 | ||
229 | #define SEQUENCE_6_SIZE 0x00000d10 | ||
230 | |||
231 | #define CMT_LUT_0_START_ADDR 0x0004b200 | ||
232 | #define CMT_LUT_0_SIZE 0x00000600 | ||
233 | |||
234 | #define CMT_LUT_1_START_ADDR 0x0004b800 | ||
235 | #define CMT_LUT_1_SIZE 0x00000600 | ||
236 | |||
237 | #define CMT_LUT_2_START_ADDR 0x0004be00 | ||
238 | #define CMT_LUT_2_SIZE 0x00000600 | ||
239 | |||
240 | #define CMT_LUT_3_START_ADDR 0x0004c400 | ||
241 | #define CMT_LUT_3_SIZE 0x00000600 | ||
242 | |||
243 | #define CMT_LUT_4_START_ADDR 0x0004ca00 | ||
244 | #define CMT_LUT_4_SIZE 0x00000600 | ||
245 | |||
246 | #define CMT_LUT_5_START_ADDR 0x0004d000 | ||
247 | #define CMT_LUT_5_SIZE 0x00000600 | ||
248 | |||
249 | #define CMT_LUT_6_START_ADDR 0x0004d600 | ||
250 | #define CMT_LUT_6_SIZE 0x00000600 | ||
251 | |||
252 | #define DRC_TABLE_0_START_ADDR 0x0004dc00 | ||
253 | #define DRC_TABLE_0_SIZE 0x00000100 | ||
254 | |||
255 | #define SPLASH_0_START_ADDR 0x0004dd00 | ||
256 | #define SPLASH_0_SIZE 0x00032280 | ||
257 | |||
258 | #define SEQUENCE_7_START_ADDR 0x00080000 | ||
259 | #define SEQUENCE_7_SIZE 0x00000d10 | ||
260 | |||
261 | #define SEQUENCE_8_START_ADDR 0x00081800 | ||
262 | #define SEQUENCE_8_SIZE 0x00000d10 | ||
263 | |||
264 | #define SEQUENCE_9_START_ADDR 0x00083000 | ||
265 | #define SEQUENCE_9_SIZE 0x00000d10 | ||
266 | |||
267 | #define CMT_LUT_7_START_ADDR 0x0008e000 | ||
268 | #define CMT_LUT_7_SIZE 0x00000600 | ||
269 | |||
270 | #define CMT_LUT_8_START_ADDR 0x0008e800 | ||
271 | #define CMT_LUT_8_SIZE 0x00000600 | ||
272 | |||
273 | #define CMT_LUT_9_START_ADDR 0x0008f000 | ||
274 | #define CMT_LUT_9_SIZE 0x00000600 | ||
275 | |||
276 | #define SPLASH_1_START_ADDR 0x0009a000 | ||
277 | #define SPLASH_1_SIZE 0x00032280 | ||
278 | |||
279 | #define SPLASH_2_START_ADDR 0x000cd000 | ||
280 | #define SPLASH_2_SIZE 0x00032280 | ||
281 | |||
282 | #define SPLASH_3_START_ADDR 0x00100000 | ||
283 | #define SPLASH_3_SIZE 0x00032280 | ||
284 | |||
285 | #define OPT_SPLASH_0_START_ADDR 0x00134000 | ||
286 | #define OPT_SPLASH_0_SIZE 0x000cb100 | ||
287 | |||
288 | #endif | ||
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c deleted file mode 100644 index 78f0a6779756..000000000000 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ /dev/null | |||
@@ -1,198 +0,0 @@ | |||
1 | /* | ||
2 | * LCD panel driver for Sharp LS037V7DW01 | ||
3 | * | ||
4 | * Copyright (C) 2008 Nokia Corporation | ||
5 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/fb.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/gpio.h> | ||
27 | |||
28 | #include <video/omapdss.h> | ||
29 | #include <video/omap-panel-data.h> | ||
30 | |||
31 | static struct omap_video_timings sharp_ls_timings = { | ||
32 | .x_res = 480, | ||
33 | .y_res = 640, | ||
34 | |||
35 | .pixel_clock = 19200, | ||
36 | |||
37 | .hsw = 2, | ||
38 | .hfp = 1, | ||
39 | .hbp = 28, | ||
40 | |||
41 | .vsw = 1, | ||
42 | .vfp = 1, | ||
43 | .vbp = 1, | ||
44 | |||
45 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
46 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
47 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
48 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
49 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
50 | }; | ||
51 | |||
52 | static inline struct panel_sharp_ls037v7dw01_data | ||
53 | *get_panel_data(const struct omap_dss_device *dssdev) | ||
54 | { | ||
55 | return (struct panel_sharp_ls037v7dw01_data *) dssdev->data; | ||
56 | } | ||
57 | |||
58 | static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) | ||
59 | { | ||
60 | struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev); | ||
61 | int r; | ||
62 | |||
63 | if (!pd) | ||
64 | return -EINVAL; | ||
65 | |||
66 | dssdev->panel.timings = sharp_ls_timings; | ||
67 | |||
68 | if (gpio_is_valid(pd->mo_gpio)) { | ||
69 | r = devm_gpio_request_one(dssdev->dev, pd->mo_gpio, | ||
70 | GPIOF_OUT_INIT_LOW, "lcd MO"); | ||
71 | if (r) | ||
72 | return r; | ||
73 | } | ||
74 | |||
75 | if (gpio_is_valid(pd->lr_gpio)) { | ||
76 | r = devm_gpio_request_one(dssdev->dev, pd->lr_gpio, | ||
77 | GPIOF_OUT_INIT_HIGH, "lcd LR"); | ||
78 | if (r) | ||
79 | return r; | ||
80 | } | ||
81 | |||
82 | if (gpio_is_valid(pd->ud_gpio)) { | ||
83 | r = devm_gpio_request_one(dssdev->dev, pd->ud_gpio, | ||
84 | GPIOF_OUT_INIT_HIGH, "lcd UD"); | ||
85 | if (r) | ||
86 | return r; | ||
87 | } | ||
88 | |||
89 | if (gpio_is_valid(pd->resb_gpio)) { | ||
90 | r = devm_gpio_request_one(dssdev->dev, pd->resb_gpio, | ||
91 | GPIOF_OUT_INIT_LOW, "lcd RESB"); | ||
92 | if (r) | ||
93 | return r; | ||
94 | } | ||
95 | |||
96 | if (gpio_is_valid(pd->ini_gpio)) { | ||
97 | r = devm_gpio_request_one(dssdev->dev, pd->ini_gpio, | ||
98 | GPIOF_OUT_INIT_LOW, "lcd INI"); | ||
99 | if (r) | ||
100 | return r; | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev) | ||
107 | { | ||
108 | } | ||
109 | |||
110 | static int sharp_ls_power_on(struct omap_dss_device *dssdev) | ||
111 | { | ||
112 | struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev); | ||
113 | int r = 0; | ||
114 | |||
115 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
116 | return 0; | ||
117 | |||
118 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
119 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
120 | |||
121 | r = omapdss_dpi_display_enable(dssdev); | ||
122 | if (r) | ||
123 | goto err0; | ||
124 | |||
125 | /* wait couple of vsyncs until enabling the LCD */ | ||
126 | msleep(50); | ||
127 | |||
128 | if (gpio_is_valid(pd->resb_gpio)) | ||
129 | gpio_set_value_cansleep(pd->resb_gpio, 1); | ||
130 | |||
131 | if (gpio_is_valid(pd->ini_gpio)) | ||
132 | gpio_set_value_cansleep(pd->ini_gpio, 1); | ||
133 | |||
134 | return 0; | ||
135 | err0: | ||
136 | return r; | ||
137 | } | ||
138 | |||
139 | static void sharp_ls_power_off(struct omap_dss_device *dssdev) | ||
140 | { | ||
141 | struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev); | ||
142 | |||
143 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
144 | return; | ||
145 | |||
146 | if (gpio_is_valid(pd->ini_gpio)) | ||
147 | gpio_set_value_cansleep(pd->ini_gpio, 0); | ||
148 | |||
149 | if (gpio_is_valid(pd->resb_gpio)) | ||
150 | gpio_set_value_cansleep(pd->resb_gpio, 0); | ||
151 | |||
152 | /* wait at least 5 vsyncs after disabling the LCD */ | ||
153 | |||
154 | msleep(100); | ||
155 | |||
156 | omapdss_dpi_display_disable(dssdev); | ||
157 | } | ||
158 | |||
159 | static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) | ||
160 | { | ||
161 | int r; | ||
162 | r = sharp_ls_power_on(dssdev); | ||
163 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
164 | return r; | ||
165 | } | ||
166 | |||
167 | static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) | ||
168 | { | ||
169 | sharp_ls_power_off(dssdev); | ||
170 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
171 | } | ||
172 | |||
173 | static struct omap_dss_driver sharp_ls_driver = { | ||
174 | .probe = sharp_ls_panel_probe, | ||
175 | .remove = __exit_p(sharp_ls_panel_remove), | ||
176 | |||
177 | .enable = sharp_ls_panel_enable, | ||
178 | .disable = sharp_ls_panel_disable, | ||
179 | |||
180 | .driver = { | ||
181 | .name = "sharp_ls_panel", | ||
182 | .owner = THIS_MODULE, | ||
183 | }, | ||
184 | }; | ||
185 | |||
186 | static int __init sharp_ls_panel_drv_init(void) | ||
187 | { | ||
188 | return omap_dss_register_driver(&sharp_ls_driver); | ||
189 | } | ||
190 | |||
191 | static void __exit sharp_ls_panel_drv_exit(void) | ||
192 | { | ||
193 | omap_dss_unregister_driver(&sharp_ls_driver); | ||
194 | } | ||
195 | |||
196 | module_init(sharp_ls_panel_drv_init); | ||
197 | module_exit(sharp_ls_panel_drv_exit); | ||
198 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c deleted file mode 100644 index 54a07da8587a..000000000000 --- a/drivers/video/omap2/displays/panel-taal.c +++ /dev/null | |||
@@ -1,1551 +0,0 @@ | |||
1 | /* | ||
2 | * Taal DSI command mode panel | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | /*#define DEBUG*/ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/jiffies.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/backlight.h> | ||
28 | #include <linux/fb.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/gpio.h> | ||
31 | #include <linux/workqueue.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/mutex.h> | ||
34 | |||
35 | #include <video/omapdss.h> | ||
36 | #include <video/omap-panel-data.h> | ||
37 | #include <video/mipi_display.h> | ||
38 | |||
39 | /* DSI Virtual channel. Hardcoded for now. */ | ||
40 | #define TCH 0 | ||
41 | |||
42 | #define DCS_READ_NUM_ERRORS 0x05 | ||
43 | #define DCS_BRIGHTNESS 0x51 | ||
44 | #define DCS_CTRL_DISPLAY 0x53 | ||
45 | #define DCS_WRITE_CABC 0x55 | ||
46 | #define DCS_READ_CABC 0x56 | ||
47 | #define DCS_GET_ID1 0xda | ||
48 | #define DCS_GET_ID2 0xdb | ||
49 | #define DCS_GET_ID3 0xdc | ||
50 | |||
51 | static irqreturn_t taal_te_isr(int irq, void *data); | ||
52 | static void taal_te_timeout_work_callback(struct work_struct *work); | ||
53 | static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); | ||
54 | |||
55 | static int taal_panel_reset(struct omap_dss_device *dssdev); | ||
56 | |||
57 | struct taal_data { | ||
58 | struct mutex lock; | ||
59 | |||
60 | struct backlight_device *bldev; | ||
61 | |||
62 | unsigned long hw_guard_end; /* next value of jiffies when we can | ||
63 | * issue the next sleep in/out command | ||
64 | */ | ||
65 | unsigned long hw_guard_wait; /* max guard time in jiffies */ | ||
66 | |||
67 | struct omap_dss_device *dssdev; | ||
68 | |||
69 | /* panel HW configuration from DT or platform data */ | ||
70 | int reset_gpio; | ||
71 | int ext_te_gpio; | ||
72 | |||
73 | bool use_dsi_backlight; | ||
74 | |||
75 | struct omap_dsi_pin_config pin_config; | ||
76 | |||
77 | /* runtime variables */ | ||
78 | bool enabled; | ||
79 | |||
80 | bool te_enabled; | ||
81 | |||
82 | atomic_t do_update; | ||
83 | int channel; | ||
84 | |||
85 | struct delayed_work te_timeout_work; | ||
86 | |||
87 | bool cabc_broken; | ||
88 | unsigned cabc_mode; | ||
89 | |||
90 | bool intro_printed; | ||
91 | |||
92 | struct workqueue_struct *workqueue; | ||
93 | |||
94 | struct delayed_work esd_work; | ||
95 | unsigned esd_interval; | ||
96 | |||
97 | bool ulps_enabled; | ||
98 | unsigned ulps_timeout; | ||
99 | struct delayed_work ulps_work; | ||
100 | }; | ||
101 | |||
102 | static void taal_esd_work(struct work_struct *work); | ||
103 | static void taal_ulps_work(struct work_struct *work); | ||
104 | |||
105 | static void hw_guard_start(struct taal_data *td, int guard_msec) | ||
106 | { | ||
107 | td->hw_guard_wait = msecs_to_jiffies(guard_msec); | ||
108 | td->hw_guard_end = jiffies + td->hw_guard_wait; | ||
109 | } | ||
110 | |||
111 | static void hw_guard_wait(struct taal_data *td) | ||
112 | { | ||
113 | unsigned long wait = td->hw_guard_end - jiffies; | ||
114 | |||
115 | if ((long)wait > 0 && wait <= td->hw_guard_wait) { | ||
116 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
117 | schedule_timeout(wait); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data) | ||
122 | { | ||
123 | int r; | ||
124 | u8 buf[1]; | ||
125 | |||
126 | r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1); | ||
127 | |||
128 | if (r < 0) | ||
129 | return r; | ||
130 | |||
131 | *data = buf[0]; | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd) | ||
137 | { | ||
138 | return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1); | ||
139 | } | ||
140 | |||
141 | static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param) | ||
142 | { | ||
143 | u8 buf[2]; | ||
144 | buf[0] = dcs_cmd; | ||
145 | buf[1] = param; | ||
146 | return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2); | ||
147 | } | ||
148 | |||
149 | static int taal_sleep_in(struct taal_data *td) | ||
150 | |||
151 | { | ||
152 | u8 cmd; | ||
153 | int r; | ||
154 | |||
155 | hw_guard_wait(td); | ||
156 | |||
157 | cmd = MIPI_DCS_ENTER_SLEEP_MODE; | ||
158 | r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1); | ||
159 | if (r) | ||
160 | return r; | ||
161 | |||
162 | hw_guard_start(td, 120); | ||
163 | |||
164 | msleep(5); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int taal_sleep_out(struct taal_data *td) | ||
170 | { | ||
171 | int r; | ||
172 | |||
173 | hw_guard_wait(td); | ||
174 | |||
175 | r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE); | ||
176 | if (r) | ||
177 | return r; | ||
178 | |||
179 | hw_guard_start(td, 120); | ||
180 | |||
181 | msleep(5); | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3) | ||
187 | { | ||
188 | int r; | ||
189 | |||
190 | r = taal_dcs_read_1(td, DCS_GET_ID1, id1); | ||
191 | if (r) | ||
192 | return r; | ||
193 | r = taal_dcs_read_1(td, DCS_GET_ID2, id2); | ||
194 | if (r) | ||
195 | return r; | ||
196 | r = taal_dcs_read_1(td, DCS_GET_ID3, id3); | ||
197 | if (r) | ||
198 | return r; | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int taal_set_update_window(struct taal_data *td, | ||
204 | u16 x, u16 y, u16 w, u16 h) | ||
205 | { | ||
206 | int r; | ||
207 | u16 x1 = x; | ||
208 | u16 x2 = x + w - 1; | ||
209 | u16 y1 = y; | ||
210 | u16 y2 = y + h - 1; | ||
211 | |||
212 | u8 buf[5]; | ||
213 | buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS; | ||
214 | buf[1] = (x1 >> 8) & 0xff; | ||
215 | buf[2] = (x1 >> 0) & 0xff; | ||
216 | buf[3] = (x2 >> 8) & 0xff; | ||
217 | buf[4] = (x2 >> 0) & 0xff; | ||
218 | |||
219 | r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf)); | ||
220 | if (r) | ||
221 | return r; | ||
222 | |||
223 | buf[0] = MIPI_DCS_SET_PAGE_ADDRESS; | ||
224 | buf[1] = (y1 >> 8) & 0xff; | ||
225 | buf[2] = (y1 >> 0) & 0xff; | ||
226 | buf[3] = (y2 >> 8) & 0xff; | ||
227 | buf[4] = (y2 >> 0) & 0xff; | ||
228 | |||
229 | r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf)); | ||
230 | if (r) | ||
231 | return r; | ||
232 | |||
233 | dsi_vc_send_bta_sync(td->dssdev, td->channel); | ||
234 | |||
235 | return r; | ||
236 | } | ||
237 | |||
238 | static void taal_queue_esd_work(struct omap_dss_device *dssdev) | ||
239 | { | ||
240 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
241 | |||
242 | if (td->esd_interval > 0) | ||
243 | queue_delayed_work(td->workqueue, &td->esd_work, | ||
244 | msecs_to_jiffies(td->esd_interval)); | ||
245 | } | ||
246 | |||
247 | static void taal_cancel_esd_work(struct omap_dss_device *dssdev) | ||
248 | { | ||
249 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
250 | |||
251 | cancel_delayed_work(&td->esd_work); | ||
252 | } | ||
253 | |||
254 | static void taal_queue_ulps_work(struct omap_dss_device *dssdev) | ||
255 | { | ||
256 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
257 | |||
258 | if (td->ulps_timeout > 0) | ||
259 | queue_delayed_work(td->workqueue, &td->ulps_work, | ||
260 | msecs_to_jiffies(td->ulps_timeout)); | ||
261 | } | ||
262 | |||
263 | static void taal_cancel_ulps_work(struct omap_dss_device *dssdev) | ||
264 | { | ||
265 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
266 | |||
267 | cancel_delayed_work(&td->ulps_work); | ||
268 | } | ||
269 | |||
270 | static int taal_enter_ulps(struct omap_dss_device *dssdev) | ||
271 | { | ||
272 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
273 | int r; | ||
274 | |||
275 | if (td->ulps_enabled) | ||
276 | return 0; | ||
277 | |||
278 | taal_cancel_ulps_work(dssdev); | ||
279 | |||
280 | r = _taal_enable_te(dssdev, false); | ||
281 | if (r) | ||
282 | goto err; | ||
283 | |||
284 | if (gpio_is_valid(td->ext_te_gpio)) | ||
285 | disable_irq(gpio_to_irq(td->ext_te_gpio)); | ||
286 | |||
287 | omapdss_dsi_display_disable(dssdev, false, true); | ||
288 | |||
289 | td->ulps_enabled = true; | ||
290 | |||
291 | return 0; | ||
292 | |||
293 | err: | ||
294 | dev_err(dssdev->dev, "enter ULPS failed"); | ||
295 | taal_panel_reset(dssdev); | ||
296 | |||
297 | td->ulps_enabled = false; | ||
298 | |||
299 | taal_queue_ulps_work(dssdev); | ||
300 | |||
301 | return r; | ||
302 | } | ||
303 | |||
304 | static int taal_exit_ulps(struct omap_dss_device *dssdev) | ||
305 | { | ||
306 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
307 | int r; | ||
308 | |||
309 | if (!td->ulps_enabled) | ||
310 | return 0; | ||
311 | |||
312 | r = omapdss_dsi_display_enable(dssdev); | ||
313 | if (r) { | ||
314 | dev_err(dssdev->dev, "failed to enable DSI\n"); | ||
315 | goto err1; | ||
316 | } | ||
317 | |||
318 | omapdss_dsi_vc_enable_hs(dssdev, td->channel, true); | ||
319 | |||
320 | r = _taal_enable_te(dssdev, true); | ||
321 | if (r) { | ||
322 | dev_err(dssdev->dev, "failed to re-enable TE"); | ||
323 | goto err2; | ||
324 | } | ||
325 | |||
326 | if (gpio_is_valid(td->ext_te_gpio)) | ||
327 | enable_irq(gpio_to_irq(td->ext_te_gpio)); | ||
328 | |||
329 | taal_queue_ulps_work(dssdev); | ||
330 | |||
331 | td->ulps_enabled = false; | ||
332 | |||
333 | return 0; | ||
334 | |||
335 | err2: | ||
336 | dev_err(dssdev->dev, "failed to exit ULPS"); | ||
337 | |||
338 | r = taal_panel_reset(dssdev); | ||
339 | if (!r) { | ||
340 | if (gpio_is_valid(td->ext_te_gpio)) | ||
341 | enable_irq(gpio_to_irq(td->ext_te_gpio)); | ||
342 | td->ulps_enabled = false; | ||
343 | } | ||
344 | err1: | ||
345 | taal_queue_ulps_work(dssdev); | ||
346 | |||
347 | return r; | ||
348 | } | ||
349 | |||
350 | static int taal_wake_up(struct omap_dss_device *dssdev) | ||
351 | { | ||
352 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
353 | |||
354 | if (td->ulps_enabled) | ||
355 | return taal_exit_ulps(dssdev); | ||
356 | |||
357 | taal_cancel_ulps_work(dssdev); | ||
358 | taal_queue_ulps_work(dssdev); | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static int taal_bl_update_status(struct backlight_device *dev) | ||
363 | { | ||
364 | struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); | ||
365 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
366 | int r; | ||
367 | int level; | ||
368 | |||
369 | if (dev->props.fb_blank == FB_BLANK_UNBLANK && | ||
370 | dev->props.power == FB_BLANK_UNBLANK) | ||
371 | level = dev->props.brightness; | ||
372 | else | ||
373 | level = 0; | ||
374 | |||
375 | dev_dbg(dssdev->dev, "update brightness to %d\n", level); | ||
376 | |||
377 | mutex_lock(&td->lock); | ||
378 | |||
379 | if (td->enabled) { | ||
380 | dsi_bus_lock(dssdev); | ||
381 | |||
382 | r = taal_wake_up(dssdev); | ||
383 | if (!r) | ||
384 | r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level); | ||
385 | |||
386 | dsi_bus_unlock(dssdev); | ||
387 | } else { | ||
388 | r = 0; | ||
389 | } | ||
390 | |||
391 | mutex_unlock(&td->lock); | ||
392 | |||
393 | return r; | ||
394 | } | ||
395 | |||
396 | static int taal_bl_get_intensity(struct backlight_device *dev) | ||
397 | { | ||
398 | if (dev->props.fb_blank == FB_BLANK_UNBLANK && | ||
399 | dev->props.power == FB_BLANK_UNBLANK) | ||
400 | return dev->props.brightness; | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static const struct backlight_ops taal_bl_ops = { | ||
406 | .get_brightness = taal_bl_get_intensity, | ||
407 | .update_status = taal_bl_update_status, | ||
408 | }; | ||
409 | |||
410 | static void taal_get_resolution(struct omap_dss_device *dssdev, | ||
411 | u16 *xres, u16 *yres) | ||
412 | { | ||
413 | *xres = dssdev->panel.timings.x_res; | ||
414 | *yres = dssdev->panel.timings.y_res; | ||
415 | } | ||
416 | |||
417 | static ssize_t taal_num_errors_show(struct device *dev, | ||
418 | struct device_attribute *attr, char *buf) | ||
419 | { | ||
420 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
421 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
422 | u8 errors = 0; | ||
423 | int r; | ||
424 | |||
425 | mutex_lock(&td->lock); | ||
426 | |||
427 | if (td->enabled) { | ||
428 | dsi_bus_lock(dssdev); | ||
429 | |||
430 | r = taal_wake_up(dssdev); | ||
431 | if (!r) | ||
432 | r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors); | ||
433 | |||
434 | dsi_bus_unlock(dssdev); | ||
435 | } else { | ||
436 | r = -ENODEV; | ||
437 | } | ||
438 | |||
439 | mutex_unlock(&td->lock); | ||
440 | |||
441 | if (r) | ||
442 | return r; | ||
443 | |||
444 | return snprintf(buf, PAGE_SIZE, "%d\n", errors); | ||
445 | } | ||
446 | |||
447 | static ssize_t taal_hw_revision_show(struct device *dev, | ||
448 | struct device_attribute *attr, char *buf) | ||
449 | { | ||
450 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
451 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
452 | u8 id1, id2, id3; | ||
453 | int r; | ||
454 | |||
455 | mutex_lock(&td->lock); | ||
456 | |||
457 | if (td->enabled) { | ||
458 | dsi_bus_lock(dssdev); | ||
459 | |||
460 | r = taal_wake_up(dssdev); | ||
461 | if (!r) | ||
462 | r = taal_get_id(td, &id1, &id2, &id3); | ||
463 | |||
464 | dsi_bus_unlock(dssdev); | ||
465 | } else { | ||
466 | r = -ENODEV; | ||
467 | } | ||
468 | |||
469 | mutex_unlock(&td->lock); | ||
470 | |||
471 | if (r) | ||
472 | return r; | ||
473 | |||
474 | return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3); | ||
475 | } | ||
476 | |||
477 | static const char *cabc_modes[] = { | ||
478 | "off", /* used also always when CABC is not supported */ | ||
479 | "ui", | ||
480 | "still-image", | ||
481 | "moving-image", | ||
482 | }; | ||
483 | |||
484 | static ssize_t show_cabc_mode(struct device *dev, | ||
485 | struct device_attribute *attr, | ||
486 | char *buf) | ||
487 | { | ||
488 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
489 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
490 | const char *mode_str; | ||
491 | int mode; | ||
492 | int len; | ||
493 | |||
494 | mode = td->cabc_mode; | ||
495 | |||
496 | mode_str = "unknown"; | ||
497 | if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes)) | ||
498 | mode_str = cabc_modes[mode]; | ||
499 | len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str); | ||
500 | |||
501 | return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1; | ||
502 | } | ||
503 | |||
504 | static ssize_t store_cabc_mode(struct device *dev, | ||
505 | struct device_attribute *attr, | ||
506 | const char *buf, size_t count) | ||
507 | { | ||
508 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
509 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
510 | int i; | ||
511 | int r; | ||
512 | |||
513 | for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { | ||
514 | if (sysfs_streq(cabc_modes[i], buf)) | ||
515 | break; | ||
516 | } | ||
517 | |||
518 | if (i == ARRAY_SIZE(cabc_modes)) | ||
519 | return -EINVAL; | ||
520 | |||
521 | mutex_lock(&td->lock); | ||
522 | |||
523 | if (td->enabled) { | ||
524 | dsi_bus_lock(dssdev); | ||
525 | |||
526 | if (!td->cabc_broken) { | ||
527 | r = taal_wake_up(dssdev); | ||
528 | if (r) | ||
529 | goto err; | ||
530 | |||
531 | r = taal_dcs_write_1(td, DCS_WRITE_CABC, i); | ||
532 | if (r) | ||
533 | goto err; | ||
534 | } | ||
535 | |||
536 | dsi_bus_unlock(dssdev); | ||
537 | } | ||
538 | |||
539 | td->cabc_mode = i; | ||
540 | |||
541 | mutex_unlock(&td->lock); | ||
542 | |||
543 | return count; | ||
544 | err: | ||
545 | dsi_bus_unlock(dssdev); | ||
546 | mutex_unlock(&td->lock); | ||
547 | return r; | ||
548 | } | ||
549 | |||
550 | static ssize_t show_cabc_available_modes(struct device *dev, | ||
551 | struct device_attribute *attr, | ||
552 | char *buf) | ||
553 | { | ||
554 | int len; | ||
555 | int i; | ||
556 | |||
557 | for (i = 0, len = 0; | ||
558 | len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++) | ||
559 | len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s", | ||
560 | i ? " " : "", cabc_modes[i], | ||
561 | i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : ""); | ||
562 | |||
563 | return len < PAGE_SIZE ? len : PAGE_SIZE - 1; | ||
564 | } | ||
565 | |||
566 | static ssize_t taal_store_esd_interval(struct device *dev, | ||
567 | struct device_attribute *attr, | ||
568 | const char *buf, size_t count) | ||
569 | { | ||
570 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
571 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
572 | |||
573 | unsigned long t; | ||
574 | int r; | ||
575 | |||
576 | r = kstrtoul(buf, 10, &t); | ||
577 | if (r) | ||
578 | return r; | ||
579 | |||
580 | mutex_lock(&td->lock); | ||
581 | taal_cancel_esd_work(dssdev); | ||
582 | td->esd_interval = t; | ||
583 | if (td->enabled) | ||
584 | taal_queue_esd_work(dssdev); | ||
585 | mutex_unlock(&td->lock); | ||
586 | |||
587 | return count; | ||
588 | } | ||
589 | |||
590 | static ssize_t taal_show_esd_interval(struct device *dev, | ||
591 | struct device_attribute *attr, | ||
592 | char *buf) | ||
593 | { | ||
594 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
595 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
596 | unsigned t; | ||
597 | |||
598 | mutex_lock(&td->lock); | ||
599 | t = td->esd_interval; | ||
600 | mutex_unlock(&td->lock); | ||
601 | |||
602 | return snprintf(buf, PAGE_SIZE, "%u\n", t); | ||
603 | } | ||
604 | |||
605 | static ssize_t taal_store_ulps(struct device *dev, | ||
606 | struct device_attribute *attr, | ||
607 | const char *buf, size_t count) | ||
608 | { | ||
609 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
610 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
611 | unsigned long t; | ||
612 | int r; | ||
613 | |||
614 | r = kstrtoul(buf, 10, &t); | ||
615 | if (r) | ||
616 | return r; | ||
617 | |||
618 | mutex_lock(&td->lock); | ||
619 | |||
620 | if (td->enabled) { | ||
621 | dsi_bus_lock(dssdev); | ||
622 | |||
623 | if (t) | ||
624 | r = taal_enter_ulps(dssdev); | ||
625 | else | ||
626 | r = taal_wake_up(dssdev); | ||
627 | |||
628 | dsi_bus_unlock(dssdev); | ||
629 | } | ||
630 | |||
631 | mutex_unlock(&td->lock); | ||
632 | |||
633 | if (r) | ||
634 | return r; | ||
635 | |||
636 | return count; | ||
637 | } | ||
638 | |||
639 | static ssize_t taal_show_ulps(struct device *dev, | ||
640 | struct device_attribute *attr, | ||
641 | char *buf) | ||
642 | { | ||
643 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
644 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
645 | unsigned t; | ||
646 | |||
647 | mutex_lock(&td->lock); | ||
648 | t = td->ulps_enabled; | ||
649 | mutex_unlock(&td->lock); | ||
650 | |||
651 | return snprintf(buf, PAGE_SIZE, "%u\n", t); | ||
652 | } | ||
653 | |||
654 | static ssize_t taal_store_ulps_timeout(struct device *dev, | ||
655 | struct device_attribute *attr, | ||
656 | const char *buf, size_t count) | ||
657 | { | ||
658 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
659 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
660 | unsigned long t; | ||
661 | int r; | ||
662 | |||
663 | r = kstrtoul(buf, 10, &t); | ||
664 | if (r) | ||
665 | return r; | ||
666 | |||
667 | mutex_lock(&td->lock); | ||
668 | td->ulps_timeout = t; | ||
669 | |||
670 | if (td->enabled) { | ||
671 | /* taal_wake_up will restart the timer */ | ||
672 | dsi_bus_lock(dssdev); | ||
673 | r = taal_wake_up(dssdev); | ||
674 | dsi_bus_unlock(dssdev); | ||
675 | } | ||
676 | |||
677 | mutex_unlock(&td->lock); | ||
678 | |||
679 | if (r) | ||
680 | return r; | ||
681 | |||
682 | return count; | ||
683 | } | ||
684 | |||
685 | static ssize_t taal_show_ulps_timeout(struct device *dev, | ||
686 | struct device_attribute *attr, | ||
687 | char *buf) | ||
688 | { | ||
689 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
690 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
691 | unsigned t; | ||
692 | |||
693 | mutex_lock(&td->lock); | ||
694 | t = td->ulps_timeout; | ||
695 | mutex_unlock(&td->lock); | ||
696 | |||
697 | return snprintf(buf, PAGE_SIZE, "%u\n", t); | ||
698 | } | ||
699 | |||
700 | static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL); | ||
701 | static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL); | ||
702 | static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, | ||
703 | show_cabc_mode, store_cabc_mode); | ||
704 | static DEVICE_ATTR(cabc_available_modes, S_IRUGO, | ||
705 | show_cabc_available_modes, NULL); | ||
706 | static DEVICE_ATTR(esd_interval, S_IRUGO | S_IWUSR, | ||
707 | taal_show_esd_interval, taal_store_esd_interval); | ||
708 | static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR, | ||
709 | taal_show_ulps, taal_store_ulps); | ||
710 | static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR, | ||
711 | taal_show_ulps_timeout, taal_store_ulps_timeout); | ||
712 | |||
713 | static struct attribute *taal_attrs[] = { | ||
714 | &dev_attr_num_dsi_errors.attr, | ||
715 | &dev_attr_hw_revision.attr, | ||
716 | &dev_attr_cabc_mode.attr, | ||
717 | &dev_attr_cabc_available_modes.attr, | ||
718 | &dev_attr_esd_interval.attr, | ||
719 | &dev_attr_ulps.attr, | ||
720 | &dev_attr_ulps_timeout.attr, | ||
721 | NULL, | ||
722 | }; | ||
723 | |||
724 | static struct attribute_group taal_attr_group = { | ||
725 | .attrs = taal_attrs, | ||
726 | }; | ||
727 | |||
728 | static void taal_hw_reset(struct omap_dss_device *dssdev) | ||
729 | { | ||
730 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
731 | |||
732 | if (!gpio_is_valid(td->reset_gpio)) | ||
733 | return; | ||
734 | |||
735 | gpio_set_value(td->reset_gpio, 1); | ||
736 | udelay(10); | ||
737 | /* reset the panel */ | ||
738 | gpio_set_value(td->reset_gpio, 0); | ||
739 | /* assert reset */ | ||
740 | udelay(10); | ||
741 | gpio_set_value(td->reset_gpio, 1); | ||
742 | /* wait after releasing reset */ | ||
743 | msleep(5); | ||
744 | } | ||
745 | |||
746 | static void taal_probe_pdata(struct taal_data *td, | ||
747 | const struct nokia_dsi_panel_data *pdata) | ||
748 | { | ||
749 | td->reset_gpio = pdata->reset_gpio; | ||
750 | |||
751 | if (pdata->use_ext_te) | ||
752 | td->ext_te_gpio = pdata->ext_te_gpio; | ||
753 | else | ||
754 | td->ext_te_gpio = -1; | ||
755 | |||
756 | td->esd_interval = pdata->esd_interval; | ||
757 | td->ulps_timeout = pdata->ulps_timeout; | ||
758 | |||
759 | td->use_dsi_backlight = pdata->use_dsi_backlight; | ||
760 | |||
761 | td->pin_config = pdata->pin_config; | ||
762 | } | ||
763 | |||
764 | static int taal_probe(struct omap_dss_device *dssdev) | ||
765 | { | ||
766 | struct backlight_properties props; | ||
767 | struct taal_data *td; | ||
768 | struct backlight_device *bldev = NULL; | ||
769 | int r; | ||
770 | |||
771 | dev_dbg(dssdev->dev, "probe\n"); | ||
772 | |||
773 | td = devm_kzalloc(dssdev->dev, sizeof(*td), GFP_KERNEL); | ||
774 | if (!td) | ||
775 | return -ENOMEM; | ||
776 | |||
777 | dev_set_drvdata(dssdev->dev, td); | ||
778 | td->dssdev = dssdev; | ||
779 | |||
780 | if (dssdev->data) { | ||
781 | const struct nokia_dsi_panel_data *pdata = dssdev->data; | ||
782 | |||
783 | taal_probe_pdata(td, pdata); | ||
784 | } else { | ||
785 | return -ENODEV; | ||
786 | } | ||
787 | |||
788 | dssdev->panel.timings.x_res = 864; | ||
789 | dssdev->panel.timings.y_res = 480; | ||
790 | dssdev->panel.timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000); | ||
791 | dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; | ||
792 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | | ||
793 | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; | ||
794 | |||
795 | mutex_init(&td->lock); | ||
796 | |||
797 | atomic_set(&td->do_update, 0); | ||
798 | |||
799 | if (gpio_is_valid(td->reset_gpio)) { | ||
800 | r = devm_gpio_request_one(dssdev->dev, td->reset_gpio, | ||
801 | GPIOF_OUT_INIT_LOW, "taal rst"); | ||
802 | if (r) { | ||
803 | dev_err(dssdev->dev, "failed to request reset gpio\n"); | ||
804 | return r; | ||
805 | } | ||
806 | } | ||
807 | |||
808 | if (gpio_is_valid(td->ext_te_gpio)) { | ||
809 | r = devm_gpio_request_one(dssdev->dev, td->ext_te_gpio, | ||
810 | GPIOF_IN, "taal irq"); | ||
811 | if (r) { | ||
812 | dev_err(dssdev->dev, "GPIO request failed\n"); | ||
813 | return r; | ||
814 | } | ||
815 | |||
816 | r = devm_request_irq(dssdev->dev, gpio_to_irq(td->ext_te_gpio), | ||
817 | taal_te_isr, | ||
818 | IRQF_TRIGGER_RISING, | ||
819 | "taal vsync", dssdev); | ||
820 | |||
821 | if (r) { | ||
822 | dev_err(dssdev->dev, "IRQ request failed\n"); | ||
823 | return r; | ||
824 | } | ||
825 | |||
826 | INIT_DEFERRABLE_WORK(&td->te_timeout_work, | ||
827 | taal_te_timeout_work_callback); | ||
828 | |||
829 | dev_dbg(dssdev->dev, "Using GPIO TE\n"); | ||
830 | } | ||
831 | |||
832 | td->workqueue = create_singlethread_workqueue("taal_esd"); | ||
833 | if (td->workqueue == NULL) { | ||
834 | dev_err(dssdev->dev, "can't create ESD workqueue\n"); | ||
835 | return -ENOMEM; | ||
836 | } | ||
837 | INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work); | ||
838 | INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work); | ||
839 | |||
840 | taal_hw_reset(dssdev); | ||
841 | |||
842 | if (td->use_dsi_backlight) { | ||
843 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
844 | props.max_brightness = 255; | ||
845 | |||
846 | props.type = BACKLIGHT_RAW; | ||
847 | bldev = backlight_device_register(dev_name(dssdev->dev), | ||
848 | dssdev->dev, dssdev, &taal_bl_ops, &props); | ||
849 | if (IS_ERR(bldev)) { | ||
850 | r = PTR_ERR(bldev); | ||
851 | goto err_bl; | ||
852 | } | ||
853 | |||
854 | td->bldev = bldev; | ||
855 | |||
856 | bldev->props.fb_blank = FB_BLANK_UNBLANK; | ||
857 | bldev->props.power = FB_BLANK_UNBLANK; | ||
858 | bldev->props.brightness = 255; | ||
859 | |||
860 | taal_bl_update_status(bldev); | ||
861 | } | ||
862 | |||
863 | r = omap_dsi_request_vc(dssdev, &td->channel); | ||
864 | if (r) { | ||
865 | dev_err(dssdev->dev, "failed to get virtual channel\n"); | ||
866 | goto err_req_vc; | ||
867 | } | ||
868 | |||
869 | r = omap_dsi_set_vc_id(dssdev, td->channel, TCH); | ||
870 | if (r) { | ||
871 | dev_err(dssdev->dev, "failed to set VC_ID\n"); | ||
872 | goto err_vc_id; | ||
873 | } | ||
874 | |||
875 | r = sysfs_create_group(&dssdev->dev->kobj, &taal_attr_group); | ||
876 | if (r) { | ||
877 | dev_err(dssdev->dev, "failed to create sysfs files\n"); | ||
878 | goto err_vc_id; | ||
879 | } | ||
880 | |||
881 | return 0; | ||
882 | |||
883 | err_vc_id: | ||
884 | omap_dsi_release_vc(dssdev, td->channel); | ||
885 | err_req_vc: | ||
886 | if (bldev != NULL) | ||
887 | backlight_device_unregister(bldev); | ||
888 | err_bl: | ||
889 | destroy_workqueue(td->workqueue); | ||
890 | return r; | ||
891 | } | ||
892 | |||
893 | static void __exit taal_remove(struct omap_dss_device *dssdev) | ||
894 | { | ||
895 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
896 | struct backlight_device *bldev; | ||
897 | |||
898 | dev_dbg(dssdev->dev, "remove\n"); | ||
899 | |||
900 | sysfs_remove_group(&dssdev->dev->kobj, &taal_attr_group); | ||
901 | omap_dsi_release_vc(dssdev, td->channel); | ||
902 | |||
903 | bldev = td->bldev; | ||
904 | if (bldev != NULL) { | ||
905 | bldev->props.power = FB_BLANK_POWERDOWN; | ||
906 | taal_bl_update_status(bldev); | ||
907 | backlight_device_unregister(bldev); | ||
908 | } | ||
909 | |||
910 | taal_cancel_ulps_work(dssdev); | ||
911 | taal_cancel_esd_work(dssdev); | ||
912 | destroy_workqueue(td->workqueue); | ||
913 | |||
914 | /* reset, to be sure that the panel is in a valid state */ | ||
915 | taal_hw_reset(dssdev); | ||
916 | } | ||
917 | |||
918 | static int taal_power_on(struct omap_dss_device *dssdev) | ||
919 | { | ||
920 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
921 | u8 id1, id2, id3; | ||
922 | int r; | ||
923 | struct omap_dss_dsi_config dsi_config = { | ||
924 | .mode = OMAP_DSS_DSI_CMD_MODE, | ||
925 | .pixel_format = OMAP_DSS_DSI_FMT_RGB888, | ||
926 | .timings = &dssdev->panel.timings, | ||
927 | .hs_clk_min = 150000000, | ||
928 | .hs_clk_max = 300000000, | ||
929 | .lp_clk_min = 7000000, | ||
930 | .lp_clk_max = 10000000, | ||
931 | }; | ||
932 | |||
933 | r = omapdss_dsi_configure_pins(dssdev, &td->pin_config); | ||
934 | if (r) { | ||
935 | dev_err(dssdev->dev, "failed to configure DSI pins\n"); | ||
936 | goto err0; | ||
937 | }; | ||
938 | |||
939 | r = omapdss_dsi_set_config(dssdev, &dsi_config); | ||
940 | if (r) { | ||
941 | dev_err(dssdev->dev, "failed to configure DSI\n"); | ||
942 | goto err0; | ||
943 | } | ||
944 | |||
945 | r = omapdss_dsi_display_enable(dssdev); | ||
946 | if (r) { | ||
947 | dev_err(dssdev->dev, "failed to enable DSI\n"); | ||
948 | goto err0; | ||
949 | } | ||
950 | |||
951 | taal_hw_reset(dssdev); | ||
952 | |||
953 | omapdss_dsi_vc_enable_hs(dssdev, td->channel, false); | ||
954 | |||
955 | r = taal_sleep_out(td); | ||
956 | if (r) | ||
957 | goto err; | ||
958 | |||
959 | r = taal_get_id(td, &id1, &id2, &id3); | ||
960 | if (r) | ||
961 | goto err; | ||
962 | |||
963 | /* on early Taal revisions CABC is broken */ | ||
964 | if (id2 == 0x00 || id2 == 0xff || id2 == 0x81) | ||
965 | td->cabc_broken = true; | ||
966 | |||
967 | r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff); | ||
968 | if (r) | ||
969 | goto err; | ||
970 | |||
971 | r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY, | ||
972 | (1<<2) | (1<<5)); /* BL | BCTRL */ | ||
973 | if (r) | ||
974 | goto err; | ||
975 | |||
976 | r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT, | ||
977 | MIPI_DCS_PIXEL_FMT_24BIT); | ||
978 | if (r) | ||
979 | goto err; | ||
980 | |||
981 | if (!td->cabc_broken) { | ||
982 | r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode); | ||
983 | if (r) | ||
984 | goto err; | ||
985 | } | ||
986 | |||
987 | r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON); | ||
988 | if (r) | ||
989 | goto err; | ||
990 | |||
991 | r = _taal_enable_te(dssdev, td->te_enabled); | ||
992 | if (r) | ||
993 | goto err; | ||
994 | |||
995 | r = dsi_enable_video_output(dssdev, td->channel); | ||
996 | if (r) | ||
997 | goto err; | ||
998 | |||
999 | td->enabled = 1; | ||
1000 | |||
1001 | if (!td->intro_printed) { | ||
1002 | dev_info(dssdev->dev, "panel revision %02x.%02x.%02x\n", | ||
1003 | id1, id2, id3); | ||
1004 | if (td->cabc_broken) | ||
1005 | dev_info(dssdev->dev, | ||
1006 | "old Taal version, CABC disabled\n"); | ||
1007 | td->intro_printed = true; | ||
1008 | } | ||
1009 | |||
1010 | omapdss_dsi_vc_enable_hs(dssdev, td->channel, true); | ||
1011 | |||
1012 | return 0; | ||
1013 | err: | ||
1014 | dev_err(dssdev->dev, "error while enabling panel, issuing HW reset\n"); | ||
1015 | |||
1016 | taal_hw_reset(dssdev); | ||
1017 | |||
1018 | omapdss_dsi_display_disable(dssdev, true, false); | ||
1019 | err0: | ||
1020 | return r; | ||
1021 | } | ||
1022 | |||
1023 | static void taal_power_off(struct omap_dss_device *dssdev) | ||
1024 | { | ||
1025 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1026 | int r; | ||
1027 | |||
1028 | dsi_disable_video_output(dssdev, td->channel); | ||
1029 | |||
1030 | r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF); | ||
1031 | if (!r) | ||
1032 | r = taal_sleep_in(td); | ||
1033 | |||
1034 | if (r) { | ||
1035 | dev_err(dssdev->dev, | ||
1036 | "error disabling panel, issuing HW reset\n"); | ||
1037 | taal_hw_reset(dssdev); | ||
1038 | } | ||
1039 | |||
1040 | omapdss_dsi_display_disable(dssdev, true, false); | ||
1041 | |||
1042 | td->enabled = 0; | ||
1043 | } | ||
1044 | |||
1045 | static int taal_panel_reset(struct omap_dss_device *dssdev) | ||
1046 | { | ||
1047 | dev_err(dssdev->dev, "performing LCD reset\n"); | ||
1048 | |||
1049 | taal_power_off(dssdev); | ||
1050 | taal_hw_reset(dssdev); | ||
1051 | return taal_power_on(dssdev); | ||
1052 | } | ||
1053 | |||
1054 | static int taal_enable(struct omap_dss_device *dssdev) | ||
1055 | { | ||
1056 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1057 | int r; | ||
1058 | |||
1059 | dev_dbg(dssdev->dev, "enable\n"); | ||
1060 | |||
1061 | mutex_lock(&td->lock); | ||
1062 | |||
1063 | if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { | ||
1064 | r = -EINVAL; | ||
1065 | goto err; | ||
1066 | } | ||
1067 | |||
1068 | dsi_bus_lock(dssdev); | ||
1069 | |||
1070 | r = taal_power_on(dssdev); | ||
1071 | |||
1072 | dsi_bus_unlock(dssdev); | ||
1073 | |||
1074 | if (r) | ||
1075 | goto err; | ||
1076 | |||
1077 | taal_queue_esd_work(dssdev); | ||
1078 | |||
1079 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
1080 | |||
1081 | mutex_unlock(&td->lock); | ||
1082 | |||
1083 | return 0; | ||
1084 | err: | ||
1085 | dev_dbg(dssdev->dev, "enable failed\n"); | ||
1086 | mutex_unlock(&td->lock); | ||
1087 | return r; | ||
1088 | } | ||
1089 | |||
1090 | static void taal_disable(struct omap_dss_device *dssdev) | ||
1091 | { | ||
1092 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1093 | |||
1094 | dev_dbg(dssdev->dev, "disable\n"); | ||
1095 | |||
1096 | mutex_lock(&td->lock); | ||
1097 | |||
1098 | taal_cancel_ulps_work(dssdev); | ||
1099 | taal_cancel_esd_work(dssdev); | ||
1100 | |||
1101 | dsi_bus_lock(dssdev); | ||
1102 | |||
1103 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | ||
1104 | int r; | ||
1105 | |||
1106 | r = taal_wake_up(dssdev); | ||
1107 | if (!r) | ||
1108 | taal_power_off(dssdev); | ||
1109 | } | ||
1110 | |||
1111 | dsi_bus_unlock(dssdev); | ||
1112 | |||
1113 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
1114 | |||
1115 | mutex_unlock(&td->lock); | ||
1116 | } | ||
1117 | |||
1118 | static void taal_framedone_cb(int err, void *data) | ||
1119 | { | ||
1120 | struct omap_dss_device *dssdev = data; | ||
1121 | dev_dbg(dssdev->dev, "framedone, err %d\n", err); | ||
1122 | dsi_bus_unlock(dssdev); | ||
1123 | } | ||
1124 | |||
1125 | static irqreturn_t taal_te_isr(int irq, void *data) | ||
1126 | { | ||
1127 | struct omap_dss_device *dssdev = data; | ||
1128 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1129 | int old; | ||
1130 | int r; | ||
1131 | |||
1132 | old = atomic_cmpxchg(&td->do_update, 1, 0); | ||
1133 | |||
1134 | if (old) { | ||
1135 | cancel_delayed_work(&td->te_timeout_work); | ||
1136 | |||
1137 | r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb, | ||
1138 | dssdev); | ||
1139 | if (r) | ||
1140 | goto err; | ||
1141 | } | ||
1142 | |||
1143 | return IRQ_HANDLED; | ||
1144 | err: | ||
1145 | dev_err(dssdev->dev, "start update failed\n"); | ||
1146 | dsi_bus_unlock(dssdev); | ||
1147 | return IRQ_HANDLED; | ||
1148 | } | ||
1149 | |||
1150 | static void taal_te_timeout_work_callback(struct work_struct *work) | ||
1151 | { | ||
1152 | struct taal_data *td = container_of(work, struct taal_data, | ||
1153 | te_timeout_work.work); | ||
1154 | struct omap_dss_device *dssdev = td->dssdev; | ||
1155 | |||
1156 | dev_err(dssdev->dev, "TE not received for 250ms!\n"); | ||
1157 | |||
1158 | atomic_set(&td->do_update, 0); | ||
1159 | dsi_bus_unlock(dssdev); | ||
1160 | } | ||
1161 | |||
1162 | static int taal_update(struct omap_dss_device *dssdev, | ||
1163 | u16 x, u16 y, u16 w, u16 h) | ||
1164 | { | ||
1165 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1166 | int r; | ||
1167 | |||
1168 | dev_dbg(dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); | ||
1169 | |||
1170 | mutex_lock(&td->lock); | ||
1171 | dsi_bus_lock(dssdev); | ||
1172 | |||
1173 | r = taal_wake_up(dssdev); | ||
1174 | if (r) | ||
1175 | goto err; | ||
1176 | |||
1177 | if (!td->enabled) { | ||
1178 | r = 0; | ||
1179 | goto err; | ||
1180 | } | ||
1181 | |||
1182 | /* XXX no need to send this every frame, but dsi break if not done */ | ||
1183 | r = taal_set_update_window(td, 0, 0, | ||
1184 | dssdev->panel.timings.x_res, | ||
1185 | dssdev->panel.timings.y_res); | ||
1186 | if (r) | ||
1187 | goto err; | ||
1188 | |||
1189 | if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) { | ||
1190 | schedule_delayed_work(&td->te_timeout_work, | ||
1191 | msecs_to_jiffies(250)); | ||
1192 | atomic_set(&td->do_update, 1); | ||
1193 | } else { | ||
1194 | r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb, | ||
1195 | dssdev); | ||
1196 | if (r) | ||
1197 | goto err; | ||
1198 | } | ||
1199 | |||
1200 | /* note: no bus_unlock here. unlock is in framedone_cb */ | ||
1201 | mutex_unlock(&td->lock); | ||
1202 | return 0; | ||
1203 | err: | ||
1204 | dsi_bus_unlock(dssdev); | ||
1205 | mutex_unlock(&td->lock); | ||
1206 | return r; | ||
1207 | } | ||
1208 | |||
1209 | static int taal_sync(struct omap_dss_device *dssdev) | ||
1210 | { | ||
1211 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1212 | |||
1213 | dev_dbg(dssdev->dev, "sync\n"); | ||
1214 | |||
1215 | mutex_lock(&td->lock); | ||
1216 | dsi_bus_lock(dssdev); | ||
1217 | dsi_bus_unlock(dssdev); | ||
1218 | mutex_unlock(&td->lock); | ||
1219 | |||
1220 | dev_dbg(dssdev->dev, "sync done\n"); | ||
1221 | |||
1222 | return 0; | ||
1223 | } | ||
1224 | |||
1225 | static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) | ||
1226 | { | ||
1227 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1228 | int r; | ||
1229 | |||
1230 | if (enable) | ||
1231 | r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0); | ||
1232 | else | ||
1233 | r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF); | ||
1234 | |||
1235 | if (!gpio_is_valid(td->ext_te_gpio)) | ||
1236 | omapdss_dsi_enable_te(dssdev, enable); | ||
1237 | |||
1238 | /* possible panel bug */ | ||
1239 | msleep(100); | ||
1240 | |||
1241 | return r; | ||
1242 | } | ||
1243 | |||
1244 | static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) | ||
1245 | { | ||
1246 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1247 | int r; | ||
1248 | |||
1249 | mutex_lock(&td->lock); | ||
1250 | |||
1251 | if (td->te_enabled == enable) | ||
1252 | goto end; | ||
1253 | |||
1254 | dsi_bus_lock(dssdev); | ||
1255 | |||
1256 | if (td->enabled) { | ||
1257 | r = taal_wake_up(dssdev); | ||
1258 | if (r) | ||
1259 | goto err; | ||
1260 | |||
1261 | r = _taal_enable_te(dssdev, enable); | ||
1262 | if (r) | ||
1263 | goto err; | ||
1264 | } | ||
1265 | |||
1266 | td->te_enabled = enable; | ||
1267 | |||
1268 | dsi_bus_unlock(dssdev); | ||
1269 | end: | ||
1270 | mutex_unlock(&td->lock); | ||
1271 | |||
1272 | return 0; | ||
1273 | err: | ||
1274 | dsi_bus_unlock(dssdev); | ||
1275 | mutex_unlock(&td->lock); | ||
1276 | |||
1277 | return r; | ||
1278 | } | ||
1279 | |||
1280 | static int taal_get_te(struct omap_dss_device *dssdev) | ||
1281 | { | ||
1282 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1283 | int r; | ||
1284 | |||
1285 | mutex_lock(&td->lock); | ||
1286 | r = td->te_enabled; | ||
1287 | mutex_unlock(&td->lock); | ||
1288 | |||
1289 | return r; | ||
1290 | } | ||
1291 | |||
1292 | static int taal_run_test(struct omap_dss_device *dssdev, int test_num) | ||
1293 | { | ||
1294 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1295 | u8 id1, id2, id3; | ||
1296 | int r; | ||
1297 | |||
1298 | mutex_lock(&td->lock); | ||
1299 | |||
1300 | if (!td->enabled) { | ||
1301 | r = -ENODEV; | ||
1302 | goto err1; | ||
1303 | } | ||
1304 | |||
1305 | dsi_bus_lock(dssdev); | ||
1306 | |||
1307 | r = taal_wake_up(dssdev); | ||
1308 | if (r) | ||
1309 | goto err2; | ||
1310 | |||
1311 | r = taal_dcs_read_1(td, DCS_GET_ID1, &id1); | ||
1312 | if (r) | ||
1313 | goto err2; | ||
1314 | r = taal_dcs_read_1(td, DCS_GET_ID2, &id2); | ||
1315 | if (r) | ||
1316 | goto err2; | ||
1317 | r = taal_dcs_read_1(td, DCS_GET_ID3, &id3); | ||
1318 | if (r) | ||
1319 | goto err2; | ||
1320 | |||
1321 | dsi_bus_unlock(dssdev); | ||
1322 | mutex_unlock(&td->lock); | ||
1323 | return 0; | ||
1324 | err2: | ||
1325 | dsi_bus_unlock(dssdev); | ||
1326 | err1: | ||
1327 | mutex_unlock(&td->lock); | ||
1328 | return r; | ||
1329 | } | ||
1330 | |||
1331 | static int taal_memory_read(struct omap_dss_device *dssdev, | ||
1332 | void *buf, size_t size, | ||
1333 | u16 x, u16 y, u16 w, u16 h) | ||
1334 | { | ||
1335 | int r; | ||
1336 | int first = 1; | ||
1337 | int plen; | ||
1338 | unsigned buf_used = 0; | ||
1339 | struct taal_data *td = dev_get_drvdata(dssdev->dev); | ||
1340 | |||
1341 | if (size < w * h * 3) | ||
1342 | return -ENOMEM; | ||
1343 | |||
1344 | mutex_lock(&td->lock); | ||
1345 | |||
1346 | if (!td->enabled) { | ||
1347 | r = -ENODEV; | ||
1348 | goto err1; | ||
1349 | } | ||
1350 | |||
1351 | size = min(w * h * 3, | ||
1352 | dssdev->panel.timings.x_res * | ||
1353 | dssdev->panel.timings.y_res * 3); | ||
1354 | |||
1355 | dsi_bus_lock(dssdev); | ||
1356 | |||
1357 | r = taal_wake_up(dssdev); | ||
1358 | if (r) | ||
1359 | goto err2; | ||
1360 | |||
1361 | /* plen 1 or 2 goes into short packet. until checksum error is fixed, | ||
1362 | * use short packets. plen 32 works, but bigger packets seem to cause | ||
1363 | * an error. */ | ||
1364 | if (size % 2) | ||
1365 | plen = 1; | ||
1366 | else | ||
1367 | plen = 2; | ||
1368 | |||
1369 | taal_set_update_window(td, x, y, w, h); | ||
1370 | |||
1371 | r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen); | ||
1372 | if (r) | ||
1373 | goto err2; | ||
1374 | |||
1375 | while (buf_used < size) { | ||
1376 | u8 dcs_cmd = first ? 0x2e : 0x3e; | ||
1377 | first = 0; | ||
1378 | |||
1379 | r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd, | ||
1380 | buf + buf_used, size - buf_used); | ||
1381 | |||
1382 | if (r < 0) { | ||
1383 | dev_err(dssdev->dev, "read error\n"); | ||
1384 | goto err3; | ||
1385 | } | ||
1386 | |||
1387 | buf_used += r; | ||
1388 | |||
1389 | if (r < plen) { | ||
1390 | dev_err(dssdev->dev, "short read\n"); | ||
1391 | break; | ||
1392 | } | ||
1393 | |||
1394 | if (signal_pending(current)) { | ||
1395 | dev_err(dssdev->dev, "signal pending, " | ||
1396 | "aborting memory read\n"); | ||
1397 | r = -ERESTARTSYS; | ||
1398 | goto err3; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | r = buf_used; | ||
1403 | |||
1404 | err3: | ||
1405 | dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1); | ||
1406 | err2: | ||
1407 | dsi_bus_unlock(dssdev); | ||
1408 | err1: | ||
1409 | mutex_unlock(&td->lock); | ||
1410 | return r; | ||
1411 | } | ||
1412 | |||
1413 | static void taal_ulps_work(struct work_struct *work) | ||
1414 | { | ||
1415 | struct taal_data *td = container_of(work, struct taal_data, | ||
1416 | ulps_work.work); | ||
1417 | struct omap_dss_device *dssdev = td->dssdev; | ||
1418 | |||
1419 | mutex_lock(&td->lock); | ||
1420 | |||
1421 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) { | ||
1422 | mutex_unlock(&td->lock); | ||
1423 | return; | ||
1424 | } | ||
1425 | |||
1426 | dsi_bus_lock(dssdev); | ||
1427 | |||
1428 | taal_enter_ulps(dssdev); | ||
1429 | |||
1430 | dsi_bus_unlock(dssdev); | ||
1431 | mutex_unlock(&td->lock); | ||
1432 | } | ||
1433 | |||
1434 | static void taal_esd_work(struct work_struct *work) | ||
1435 | { | ||
1436 | struct taal_data *td = container_of(work, struct taal_data, | ||
1437 | esd_work.work); | ||
1438 | struct omap_dss_device *dssdev = td->dssdev; | ||
1439 | u8 state1, state2; | ||
1440 | int r; | ||
1441 | |||
1442 | mutex_lock(&td->lock); | ||
1443 | |||
1444 | if (!td->enabled) { | ||
1445 | mutex_unlock(&td->lock); | ||
1446 | return; | ||
1447 | } | ||
1448 | |||
1449 | dsi_bus_lock(dssdev); | ||
1450 | |||
1451 | r = taal_wake_up(dssdev); | ||
1452 | if (r) { | ||
1453 | dev_err(dssdev->dev, "failed to exit ULPS\n"); | ||
1454 | goto err; | ||
1455 | } | ||
1456 | |||
1457 | r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1); | ||
1458 | if (r) { | ||
1459 | dev_err(dssdev->dev, "failed to read Taal status\n"); | ||
1460 | goto err; | ||
1461 | } | ||
1462 | |||
1463 | /* Run self diagnostics */ | ||
1464 | r = taal_sleep_out(td); | ||
1465 | if (r) { | ||
1466 | dev_err(dssdev->dev, "failed to run Taal self-diagnostics\n"); | ||
1467 | goto err; | ||
1468 | } | ||
1469 | |||
1470 | r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2); | ||
1471 | if (r) { | ||
1472 | dev_err(dssdev->dev, "failed to read Taal status\n"); | ||
1473 | goto err; | ||
1474 | } | ||
1475 | |||
1476 | /* Each sleep out command will trigger a self diagnostic and flip | ||
1477 | * Bit6 if the test passes. | ||
1478 | */ | ||
1479 | if (!((state1 ^ state2) & (1 << 6))) { | ||
1480 | dev_err(dssdev->dev, "LCD self diagnostics failed\n"); | ||
1481 | goto err; | ||
1482 | } | ||
1483 | /* Self-diagnostics result is also shown on TE GPIO line. We need | ||
1484 | * to re-enable TE after self diagnostics */ | ||
1485 | if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) { | ||
1486 | r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0); | ||
1487 | if (r) | ||
1488 | goto err; | ||
1489 | } | ||
1490 | |||
1491 | dsi_bus_unlock(dssdev); | ||
1492 | |||
1493 | taal_queue_esd_work(dssdev); | ||
1494 | |||
1495 | mutex_unlock(&td->lock); | ||
1496 | return; | ||
1497 | err: | ||
1498 | dev_err(dssdev->dev, "performing LCD reset\n"); | ||
1499 | |||
1500 | taal_panel_reset(dssdev); | ||
1501 | |||
1502 | dsi_bus_unlock(dssdev); | ||
1503 | |||
1504 | taal_queue_esd_work(dssdev); | ||
1505 | |||
1506 | mutex_unlock(&td->lock); | ||
1507 | } | ||
1508 | |||
1509 | static struct omap_dss_driver taal_driver = { | ||
1510 | .probe = taal_probe, | ||
1511 | .remove = __exit_p(taal_remove), | ||
1512 | |||
1513 | .enable = taal_enable, | ||
1514 | .disable = taal_disable, | ||
1515 | |||
1516 | .update = taal_update, | ||
1517 | .sync = taal_sync, | ||
1518 | |||
1519 | .get_resolution = taal_get_resolution, | ||
1520 | .get_recommended_bpp = omapdss_default_get_recommended_bpp, | ||
1521 | |||
1522 | .enable_te = taal_enable_te, | ||
1523 | .get_te = taal_get_te, | ||
1524 | |||
1525 | .run_test = taal_run_test, | ||
1526 | .memory_read = taal_memory_read, | ||
1527 | |||
1528 | .driver = { | ||
1529 | .name = "taal", | ||
1530 | .owner = THIS_MODULE, | ||
1531 | }, | ||
1532 | }; | ||
1533 | |||
1534 | static int __init taal_init(void) | ||
1535 | { | ||
1536 | omap_dss_register_driver(&taal_driver); | ||
1537 | |||
1538 | return 0; | ||
1539 | } | ||
1540 | |||
1541 | static void __exit taal_exit(void) | ||
1542 | { | ||
1543 | omap_dss_unregister_driver(&taal_driver); | ||
1544 | } | ||
1545 | |||
1546 | module_init(taal_init); | ||
1547 | module_exit(taal_exit); | ||
1548 | |||
1549 | MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); | ||
1550 | MODULE_DESCRIPTION("Taal Driver"); | ||
1551 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c deleted file mode 100644 index 1fdfb158a2a9..000000000000 --- a/drivers/video/omap2/displays/panel-tfp410.c +++ /dev/null | |||
@@ -1,353 +0,0 @@ | |||
1 | /* | ||
2 | * TFP410 DPI-to-DVI chip | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments Inc | ||
5 | * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <video/omapdss.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/gpio.h> | ||
25 | #include <drm/drm_edid.h> | ||
26 | |||
27 | #include <video/omap-panel-data.h> | ||
28 | |||
29 | static const struct omap_video_timings tfp410_default_timings = { | ||
30 | .x_res = 640, | ||
31 | .y_res = 480, | ||
32 | |||
33 | .pixel_clock = 23500, | ||
34 | |||
35 | .hfp = 48, | ||
36 | .hsw = 32, | ||
37 | .hbp = 80, | ||
38 | |||
39 | .vfp = 3, | ||
40 | .vsw = 4, | ||
41 | .vbp = 7, | ||
42 | |||
43 | .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
44 | .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
45 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, | ||
46 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
47 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
48 | }; | ||
49 | |||
50 | struct panel_drv_data { | ||
51 | struct omap_dss_device *dssdev; | ||
52 | |||
53 | struct mutex lock; | ||
54 | |||
55 | int pd_gpio; | ||
56 | |||
57 | struct i2c_adapter *i2c_adapter; | ||
58 | }; | ||
59 | |||
60 | static int tfp410_power_on(struct omap_dss_device *dssdev) | ||
61 | { | ||
62 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
63 | int r; | ||
64 | |||
65 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
66 | return 0; | ||
67 | |||
68 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
69 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
70 | |||
71 | r = omapdss_dpi_display_enable(dssdev); | ||
72 | if (r) | ||
73 | goto err0; | ||
74 | |||
75 | if (gpio_is_valid(ddata->pd_gpio)) | ||
76 | gpio_set_value_cansleep(ddata->pd_gpio, 1); | ||
77 | |||
78 | return 0; | ||
79 | err0: | ||
80 | return r; | ||
81 | } | ||
82 | |||
83 | static void tfp410_power_off(struct omap_dss_device *dssdev) | ||
84 | { | ||
85 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
86 | |||
87 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
88 | return; | ||
89 | |||
90 | if (gpio_is_valid(ddata->pd_gpio)) | ||
91 | gpio_set_value_cansleep(ddata->pd_gpio, 0); | ||
92 | |||
93 | omapdss_dpi_display_disable(dssdev); | ||
94 | } | ||
95 | |||
96 | static int tfp410_probe(struct omap_dss_device *dssdev) | ||
97 | { | ||
98 | struct panel_drv_data *ddata; | ||
99 | int r; | ||
100 | int i2c_bus_num; | ||
101 | |||
102 | ddata = devm_kzalloc(dssdev->dev, sizeof(*ddata), GFP_KERNEL); | ||
103 | if (!ddata) | ||
104 | return -ENOMEM; | ||
105 | |||
106 | dssdev->panel.timings = tfp410_default_timings; | ||
107 | |||
108 | ddata->dssdev = dssdev; | ||
109 | mutex_init(&ddata->lock); | ||
110 | |||
111 | if (dssdev->data) { | ||
112 | struct tfp410_platform_data *pdata = dssdev->data; | ||
113 | |||
114 | ddata->pd_gpio = pdata->power_down_gpio; | ||
115 | i2c_bus_num = pdata->i2c_bus_num; | ||
116 | } else { | ||
117 | ddata->pd_gpio = -1; | ||
118 | i2c_bus_num = -1; | ||
119 | } | ||
120 | |||
121 | if (gpio_is_valid(ddata->pd_gpio)) { | ||
122 | r = devm_gpio_request_one(dssdev->dev, ddata->pd_gpio, | ||
123 | GPIOF_OUT_INIT_LOW, "tfp410 pd"); | ||
124 | if (r) { | ||
125 | dev_err(dssdev->dev, "Failed to request PD GPIO %d\n", | ||
126 | ddata->pd_gpio); | ||
127 | return r; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | if (i2c_bus_num != -1) { | ||
132 | struct i2c_adapter *adapter; | ||
133 | |||
134 | adapter = i2c_get_adapter(i2c_bus_num); | ||
135 | if (!adapter) { | ||
136 | dev_err(dssdev->dev, "Failed to get I2C adapter, bus %d\n", | ||
137 | i2c_bus_num); | ||
138 | return -EPROBE_DEFER; | ||
139 | } | ||
140 | |||
141 | ddata->i2c_adapter = adapter; | ||
142 | } | ||
143 | |||
144 | dev_set_drvdata(dssdev->dev, ddata); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static void __exit tfp410_remove(struct omap_dss_device *dssdev) | ||
150 | { | ||
151 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
152 | |||
153 | mutex_lock(&ddata->lock); | ||
154 | |||
155 | if (ddata->i2c_adapter) | ||
156 | i2c_put_adapter(ddata->i2c_adapter); | ||
157 | |||
158 | dev_set_drvdata(dssdev->dev, NULL); | ||
159 | |||
160 | mutex_unlock(&ddata->lock); | ||
161 | } | ||
162 | |||
163 | static int tfp410_enable(struct omap_dss_device *dssdev) | ||
164 | { | ||
165 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
166 | int r; | ||
167 | |||
168 | mutex_lock(&ddata->lock); | ||
169 | |||
170 | r = tfp410_power_on(dssdev); | ||
171 | if (r == 0) | ||
172 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
173 | |||
174 | mutex_unlock(&ddata->lock); | ||
175 | |||
176 | return r; | ||
177 | } | ||
178 | |||
179 | static void tfp410_disable(struct omap_dss_device *dssdev) | ||
180 | { | ||
181 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
182 | |||
183 | mutex_lock(&ddata->lock); | ||
184 | |||
185 | tfp410_power_off(dssdev); | ||
186 | |||
187 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
188 | |||
189 | mutex_unlock(&ddata->lock); | ||
190 | } | ||
191 | |||
192 | static void tfp410_set_timings(struct omap_dss_device *dssdev, | ||
193 | struct omap_video_timings *timings) | ||
194 | { | ||
195 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
196 | |||
197 | mutex_lock(&ddata->lock); | ||
198 | omapdss_dpi_set_timings(dssdev, timings); | ||
199 | dssdev->panel.timings = *timings; | ||
200 | mutex_unlock(&ddata->lock); | ||
201 | } | ||
202 | |||
203 | static void tfp410_get_timings(struct omap_dss_device *dssdev, | ||
204 | struct omap_video_timings *timings) | ||
205 | { | ||
206 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
207 | |||
208 | mutex_lock(&ddata->lock); | ||
209 | *timings = dssdev->panel.timings; | ||
210 | mutex_unlock(&ddata->lock); | ||
211 | } | ||
212 | |||
213 | static int tfp410_check_timings(struct omap_dss_device *dssdev, | ||
214 | struct omap_video_timings *timings) | ||
215 | { | ||
216 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
217 | int r; | ||
218 | |||
219 | mutex_lock(&ddata->lock); | ||
220 | r = dpi_check_timings(dssdev, timings); | ||
221 | mutex_unlock(&ddata->lock); | ||
222 | |||
223 | return r; | ||
224 | } | ||
225 | |||
226 | |||
227 | static int tfp410_ddc_read(struct i2c_adapter *adapter, | ||
228 | unsigned char *buf, u16 count, u8 offset) | ||
229 | { | ||
230 | int r, retries; | ||
231 | |||
232 | for (retries = 3; retries > 0; retries--) { | ||
233 | struct i2c_msg msgs[] = { | ||
234 | { | ||
235 | .addr = DDC_ADDR, | ||
236 | .flags = 0, | ||
237 | .len = 1, | ||
238 | .buf = &offset, | ||
239 | }, { | ||
240 | .addr = DDC_ADDR, | ||
241 | .flags = I2C_M_RD, | ||
242 | .len = count, | ||
243 | .buf = buf, | ||
244 | } | ||
245 | }; | ||
246 | |||
247 | r = i2c_transfer(adapter, msgs, 2); | ||
248 | if (r == 2) | ||
249 | return 0; | ||
250 | |||
251 | if (r != -EAGAIN) | ||
252 | break; | ||
253 | } | ||
254 | |||
255 | return r < 0 ? r : -EIO; | ||
256 | } | ||
257 | |||
258 | static int tfp410_read_edid(struct omap_dss_device *dssdev, | ||
259 | u8 *edid, int len) | ||
260 | { | ||
261 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
262 | int r, l, bytes_read; | ||
263 | |||
264 | mutex_lock(&ddata->lock); | ||
265 | |||
266 | if (!ddata->i2c_adapter) { | ||
267 | r = -ENODEV; | ||
268 | goto err; | ||
269 | } | ||
270 | |||
271 | l = min(EDID_LENGTH, len); | ||
272 | r = tfp410_ddc_read(ddata->i2c_adapter, edid, l, 0); | ||
273 | if (r) | ||
274 | goto err; | ||
275 | |||
276 | bytes_read = l; | ||
277 | |||
278 | /* if there are extensions, read second block */ | ||
279 | if (len > EDID_LENGTH && edid[0x7e] > 0) { | ||
280 | l = min(EDID_LENGTH, len - EDID_LENGTH); | ||
281 | |||
282 | r = tfp410_ddc_read(ddata->i2c_adapter, edid + EDID_LENGTH, | ||
283 | l, EDID_LENGTH); | ||
284 | if (r) | ||
285 | goto err; | ||
286 | |||
287 | bytes_read += l; | ||
288 | } | ||
289 | |||
290 | mutex_unlock(&ddata->lock); | ||
291 | |||
292 | return bytes_read; | ||
293 | |||
294 | err: | ||
295 | mutex_unlock(&ddata->lock); | ||
296 | return r; | ||
297 | } | ||
298 | |||
299 | static bool tfp410_detect(struct omap_dss_device *dssdev) | ||
300 | { | ||
301 | struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); | ||
302 | unsigned char out; | ||
303 | int r; | ||
304 | |||
305 | mutex_lock(&ddata->lock); | ||
306 | |||
307 | if (!ddata->i2c_adapter) | ||
308 | goto out; | ||
309 | |||
310 | r = tfp410_ddc_read(ddata->i2c_adapter, &out, 1, 0); | ||
311 | |||
312 | mutex_unlock(&ddata->lock); | ||
313 | |||
314 | return r == 0; | ||
315 | |||
316 | out: | ||
317 | mutex_unlock(&ddata->lock); | ||
318 | return true; | ||
319 | } | ||
320 | |||
321 | static struct omap_dss_driver tfp410_driver = { | ||
322 | .probe = tfp410_probe, | ||
323 | .remove = __exit_p(tfp410_remove), | ||
324 | |||
325 | .enable = tfp410_enable, | ||
326 | .disable = tfp410_disable, | ||
327 | |||
328 | .set_timings = tfp410_set_timings, | ||
329 | .get_timings = tfp410_get_timings, | ||
330 | .check_timings = tfp410_check_timings, | ||
331 | |||
332 | .read_edid = tfp410_read_edid, | ||
333 | .detect = tfp410_detect, | ||
334 | |||
335 | .driver = { | ||
336 | .name = "tfp410", | ||
337 | .owner = THIS_MODULE, | ||
338 | }, | ||
339 | }; | ||
340 | |||
341 | static int __init tfp410_init(void) | ||
342 | { | ||
343 | return omap_dss_register_driver(&tfp410_driver); | ||
344 | } | ||
345 | |||
346 | static void __exit tfp410_exit(void) | ||
347 | { | ||
348 | omap_dss_unregister_driver(&tfp410_driver); | ||
349 | } | ||
350 | |||
351 | module_init(tfp410_init); | ||
352 | module_exit(tfp410_exit); | ||
353 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c deleted file mode 100644 index 7729b6fa6f97..000000000000 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ /dev/null | |||
@@ -1,596 +0,0 @@ | |||
1 | /* | ||
2 | * LCD panel driver for TPO TD043MTEA1 | ||
3 | * | ||
4 | * Author: Gražvydas Ignotas <notasas@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/spi/spi.h> | ||
15 | #include <linux/regulator/consumer.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | #include <video/omapdss.h> | ||
21 | #include <video/omap-panel-data.h> | ||
22 | |||
23 | #define TPO_R02_MODE(x) ((x) & 7) | ||
24 | #define TPO_R02_MODE_800x480 7 | ||
25 | #define TPO_R02_NCLK_RISING BIT(3) | ||
26 | #define TPO_R02_HSYNC_HIGH BIT(4) | ||
27 | #define TPO_R02_VSYNC_HIGH BIT(5) | ||
28 | |||
29 | #define TPO_R03_NSTANDBY BIT(0) | ||
30 | #define TPO_R03_EN_CP_CLK BIT(1) | ||
31 | #define TPO_R03_EN_VGL_PUMP BIT(2) | ||
32 | #define TPO_R03_EN_PWM BIT(3) | ||
33 | #define TPO_R03_DRIVING_CAP_100 BIT(4) | ||
34 | #define TPO_R03_EN_PRE_CHARGE BIT(6) | ||
35 | #define TPO_R03_SOFTWARE_CTL BIT(7) | ||
36 | |||
37 | #define TPO_R04_NFLIP_H BIT(0) | ||
38 | #define TPO_R04_NFLIP_V BIT(1) | ||
39 | #define TPO_R04_CP_CLK_FREQ_1H BIT(2) | ||
40 | #define TPO_R04_VGL_FREQ_1H BIT(4) | ||
41 | |||
42 | #define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \ | ||
43 | TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \ | ||
44 | TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \ | ||
45 | TPO_R03_SOFTWARE_CTL) | ||
46 | |||
47 | #define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \ | ||
48 | TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) | ||
49 | |||
50 | static const u16 tpo_td043_def_gamma[12] = { | ||
51 | 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023 | ||
52 | }; | ||
53 | |||
54 | struct tpo_td043_device { | ||
55 | struct spi_device *spi; | ||
56 | struct regulator *vcc_reg; | ||
57 | int nreset_gpio; | ||
58 | u16 gamma[12]; | ||
59 | u32 mode; | ||
60 | u32 hmirror:1; | ||
61 | u32 vmirror:1; | ||
62 | u32 powered_on:1; | ||
63 | u32 spi_suspended:1; | ||
64 | u32 power_on_resume:1; | ||
65 | }; | ||
66 | |||
67 | /* used to pass spi_device from SPI to DSS portion of the driver */ | ||
68 | static struct tpo_td043_device *g_tpo_td043; | ||
69 | |||
70 | static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) | ||
71 | { | ||
72 | struct spi_message m; | ||
73 | struct spi_transfer xfer; | ||
74 | u16 w; | ||
75 | int r; | ||
76 | |||
77 | spi_message_init(&m); | ||
78 | |||
79 | memset(&xfer, 0, sizeof(xfer)); | ||
80 | |||
81 | w = ((u16)addr << 10) | (1 << 8) | data; | ||
82 | xfer.tx_buf = &w; | ||
83 | xfer.bits_per_word = 16; | ||
84 | xfer.len = 2; | ||
85 | spi_message_add_tail(&xfer, &m); | ||
86 | |||
87 | r = spi_sync(spi, &m); | ||
88 | if (r < 0) | ||
89 | dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r); | ||
90 | return r; | ||
91 | } | ||
92 | |||
93 | static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12]) | ||
94 | { | ||
95 | u8 i, val; | ||
96 | |||
97 | /* gamma bits [9:8] */ | ||
98 | for (val = i = 0; i < 4; i++) | ||
99 | val |= (gamma[i] & 0x300) >> ((i + 1) * 2); | ||
100 | tpo_td043_write(spi, 0x11, val); | ||
101 | |||
102 | for (val = i = 0; i < 4; i++) | ||
103 | val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2); | ||
104 | tpo_td043_write(spi, 0x12, val); | ||
105 | |||
106 | for (val = i = 0; i < 4; i++) | ||
107 | val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2); | ||
108 | tpo_td043_write(spi, 0x13, val); | ||
109 | |||
110 | /* gamma bits [7:0] */ | ||
111 | for (val = i = 0; i < 12; i++) | ||
112 | tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff); | ||
113 | } | ||
114 | |||
115 | static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) | ||
116 | { | ||
117 | u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \ | ||
118 | TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H; | ||
119 | if (h) | ||
120 | reg4 &= ~TPO_R04_NFLIP_H; | ||
121 | if (v) | ||
122 | reg4 &= ~TPO_R04_NFLIP_V; | ||
123 | |||
124 | return tpo_td043_write(spi, 4, reg4); | ||
125 | } | ||
126 | |||
127 | static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) | ||
128 | { | ||
129 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); | ||
130 | |||
131 | tpo_td043->hmirror = enable; | ||
132 | return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, | ||
133 | tpo_td043->vmirror); | ||
134 | } | ||
135 | |||
136 | static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) | ||
137 | { | ||
138 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); | ||
139 | |||
140 | return tpo_td043->hmirror; | ||
141 | } | ||
142 | |||
143 | static ssize_t tpo_td043_vmirror_show(struct device *dev, | ||
144 | struct device_attribute *attr, char *buf) | ||
145 | { | ||
146 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
147 | |||
148 | return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror); | ||
149 | } | ||
150 | |||
151 | static ssize_t tpo_td043_vmirror_store(struct device *dev, | ||
152 | struct device_attribute *attr, const char *buf, size_t count) | ||
153 | { | ||
154 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
155 | int val; | ||
156 | int ret; | ||
157 | |||
158 | ret = kstrtoint(buf, 0, &val); | ||
159 | if (ret < 0) | ||
160 | return ret; | ||
161 | |||
162 | val = !!val; | ||
163 | |||
164 | ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val); | ||
165 | if (ret < 0) | ||
166 | return ret; | ||
167 | |||
168 | tpo_td043->vmirror = val; | ||
169 | |||
170 | return count; | ||
171 | } | ||
172 | |||
173 | static ssize_t tpo_td043_mode_show(struct device *dev, | ||
174 | struct device_attribute *attr, char *buf) | ||
175 | { | ||
176 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
177 | |||
178 | return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode); | ||
179 | } | ||
180 | |||
181 | static ssize_t tpo_td043_mode_store(struct device *dev, | ||
182 | struct device_attribute *attr, const char *buf, size_t count) | ||
183 | { | ||
184 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
185 | long val; | ||
186 | int ret; | ||
187 | |||
188 | ret = kstrtol(buf, 0, &val); | ||
189 | if (ret != 0 || val & ~7) | ||
190 | return -EINVAL; | ||
191 | |||
192 | tpo_td043->mode = val; | ||
193 | |||
194 | val |= TPO_R02_NCLK_RISING; | ||
195 | tpo_td043_write(tpo_td043->spi, 2, val); | ||
196 | |||
197 | return count; | ||
198 | } | ||
199 | |||
200 | static ssize_t tpo_td043_gamma_show(struct device *dev, | ||
201 | struct device_attribute *attr, char *buf) | ||
202 | { | ||
203 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
204 | ssize_t len = 0; | ||
205 | int ret; | ||
206 | int i; | ||
207 | |||
208 | for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) { | ||
209 | ret = snprintf(buf + len, PAGE_SIZE - len, "%u ", | ||
210 | tpo_td043->gamma[i]); | ||
211 | if (ret < 0) | ||
212 | return ret; | ||
213 | len += ret; | ||
214 | } | ||
215 | buf[len - 1] = '\n'; | ||
216 | |||
217 | return len; | ||
218 | } | ||
219 | |||
220 | static ssize_t tpo_td043_gamma_store(struct device *dev, | ||
221 | struct device_attribute *attr, const char *buf, size_t count) | ||
222 | { | ||
223 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
224 | unsigned int g[12]; | ||
225 | int ret; | ||
226 | int i; | ||
227 | |||
228 | ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u", | ||
229 | &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], | ||
230 | &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); | ||
231 | |||
232 | if (ret != 12) | ||
233 | return -EINVAL; | ||
234 | |||
235 | for (i = 0; i < 12; i++) | ||
236 | tpo_td043->gamma[i] = g[i]; | ||
237 | |||
238 | tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); | ||
239 | |||
240 | return count; | ||
241 | } | ||
242 | |||
243 | static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR, | ||
244 | tpo_td043_vmirror_show, tpo_td043_vmirror_store); | ||
245 | static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, | ||
246 | tpo_td043_mode_show, tpo_td043_mode_store); | ||
247 | static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR, | ||
248 | tpo_td043_gamma_show, tpo_td043_gamma_store); | ||
249 | |||
250 | static struct attribute *tpo_td043_attrs[] = { | ||
251 | &dev_attr_vmirror.attr, | ||
252 | &dev_attr_mode.attr, | ||
253 | &dev_attr_gamma.attr, | ||
254 | NULL, | ||
255 | }; | ||
256 | |||
257 | static struct attribute_group tpo_td043_attr_group = { | ||
258 | .attrs = tpo_td043_attrs, | ||
259 | }; | ||
260 | |||
261 | static const struct omap_video_timings tpo_td043_timings = { | ||
262 | .x_res = 800, | ||
263 | .y_res = 480, | ||
264 | |||
265 | .pixel_clock = 36000, | ||
266 | |||
267 | .hsw = 1, | ||
268 | .hfp = 68, | ||
269 | .hbp = 214, | ||
270 | |||
271 | .vsw = 1, | ||
272 | .vfp = 39, | ||
273 | .vbp = 34, | ||
274 | |||
275 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
276 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
277 | .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, | ||
278 | .de_level = OMAPDSS_SIG_ACTIVE_HIGH, | ||
279 | .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, | ||
280 | }; | ||
281 | |||
282 | static inline struct panel_tpo_td043_data | ||
283 | *get_panel_data(const struct omap_dss_device *dssdev) | ||
284 | { | ||
285 | return (struct panel_tpo_td043_data *) dssdev->data; | ||
286 | } | ||
287 | |||
288 | static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) | ||
289 | { | ||
290 | int r; | ||
291 | |||
292 | if (tpo_td043->powered_on) | ||
293 | return 0; | ||
294 | |||
295 | r = regulator_enable(tpo_td043->vcc_reg); | ||
296 | if (r != 0) | ||
297 | return r; | ||
298 | |||
299 | /* wait for panel to stabilize */ | ||
300 | msleep(160); | ||
301 | |||
302 | if (gpio_is_valid(tpo_td043->nreset_gpio)) | ||
303 | gpio_set_value(tpo_td043->nreset_gpio, 1); | ||
304 | |||
305 | tpo_td043_write(tpo_td043->spi, 2, | ||
306 | TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING); | ||
307 | tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL); | ||
308 | tpo_td043_write(tpo_td043->spi, 0x20, 0xf0); | ||
309 | tpo_td043_write(tpo_td043->spi, 0x21, 0xf0); | ||
310 | tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, | ||
311 | tpo_td043->vmirror); | ||
312 | tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); | ||
313 | |||
314 | tpo_td043->powered_on = 1; | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043) | ||
319 | { | ||
320 | if (!tpo_td043->powered_on) | ||
321 | return; | ||
322 | |||
323 | tpo_td043_write(tpo_td043->spi, 3, | ||
324 | TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); | ||
325 | |||
326 | if (gpio_is_valid(tpo_td043->nreset_gpio)) | ||
327 | gpio_set_value(tpo_td043->nreset_gpio, 0); | ||
328 | |||
329 | /* wait for at least 2 vsyncs before cutting off power */ | ||
330 | msleep(50); | ||
331 | |||
332 | tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY); | ||
333 | |||
334 | regulator_disable(tpo_td043->vcc_reg); | ||
335 | |||
336 | tpo_td043->powered_on = 0; | ||
337 | } | ||
338 | |||
339 | static int tpo_td043_enable_dss(struct omap_dss_device *dssdev) | ||
340 | { | ||
341 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); | ||
342 | int r; | ||
343 | |||
344 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | ||
345 | return 0; | ||
346 | |||
347 | omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); | ||
348 | omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); | ||
349 | |||
350 | r = omapdss_dpi_display_enable(dssdev); | ||
351 | if (r) | ||
352 | goto err0; | ||
353 | |||
354 | /* | ||
355 | * If we are resuming from system suspend, SPI clocks might not be | ||
356 | * enabled yet, so we'll program the LCD from SPI PM resume callback. | ||
357 | */ | ||
358 | if (!tpo_td043->spi_suspended) { | ||
359 | r = tpo_td043_power_on(tpo_td043); | ||
360 | if (r) | ||
361 | goto err1; | ||
362 | } | ||
363 | |||
364 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
365 | |||
366 | return 0; | ||
367 | err1: | ||
368 | omapdss_dpi_display_disable(dssdev); | ||
369 | err0: | ||
370 | return r; | ||
371 | } | ||
372 | |||
373 | static void tpo_td043_disable_dss(struct omap_dss_device *dssdev) | ||
374 | { | ||
375 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); | ||
376 | |||
377 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
378 | return; | ||
379 | |||
380 | omapdss_dpi_display_disable(dssdev); | ||
381 | |||
382 | if (!tpo_td043->spi_suspended) | ||
383 | tpo_td043_power_off(tpo_td043); | ||
384 | } | ||
385 | |||
386 | static int tpo_td043_enable(struct omap_dss_device *dssdev) | ||
387 | { | ||
388 | dev_dbg(dssdev->dev, "enable\n"); | ||
389 | |||
390 | return tpo_td043_enable_dss(dssdev); | ||
391 | } | ||
392 | |||
393 | static void tpo_td043_disable(struct omap_dss_device *dssdev) | ||
394 | { | ||
395 | dev_dbg(dssdev->dev, "disable\n"); | ||
396 | |||
397 | tpo_td043_disable_dss(dssdev); | ||
398 | |||
399 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
400 | } | ||
401 | |||
402 | static int tpo_td043_probe(struct omap_dss_device *dssdev) | ||
403 | { | ||
404 | struct tpo_td043_device *tpo_td043 = g_tpo_td043; | ||
405 | struct panel_tpo_td043_data *pdata = get_panel_data(dssdev); | ||
406 | int ret = 0; | ||
407 | |||
408 | dev_dbg(dssdev->dev, "probe\n"); | ||
409 | |||
410 | if (tpo_td043 == NULL) { | ||
411 | dev_err(dssdev->dev, "missing tpo_td043_device\n"); | ||
412 | return -ENODEV; | ||
413 | } | ||
414 | |||
415 | if (!pdata) | ||
416 | return -EINVAL; | ||
417 | |||
418 | tpo_td043->nreset_gpio = pdata->nreset_gpio; | ||
419 | |||
420 | dssdev->panel.timings = tpo_td043_timings; | ||
421 | dssdev->ctrl.pixel_size = 24; | ||
422 | |||
423 | tpo_td043->mode = TPO_R02_MODE_800x480; | ||
424 | memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma)); | ||
425 | |||
426 | tpo_td043->vcc_reg = regulator_get(dssdev->dev, "vcc"); | ||
427 | if (IS_ERR(tpo_td043->vcc_reg)) { | ||
428 | dev_err(dssdev->dev, "failed to get LCD VCC regulator\n"); | ||
429 | ret = PTR_ERR(tpo_td043->vcc_reg); | ||
430 | goto fail_regulator; | ||
431 | } | ||
432 | |||
433 | if (gpio_is_valid(tpo_td043->nreset_gpio)) { | ||
434 | ret = devm_gpio_request_one(dssdev->dev, | ||
435 | tpo_td043->nreset_gpio, GPIOF_OUT_INIT_LOW, | ||
436 | "lcd reset"); | ||
437 | if (ret < 0) { | ||
438 | dev_err(dssdev->dev, "couldn't request reset GPIO\n"); | ||
439 | goto fail_gpio_req; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | ret = sysfs_create_group(&dssdev->dev->kobj, &tpo_td043_attr_group); | ||
444 | if (ret) | ||
445 | dev_warn(dssdev->dev, "failed to create sysfs files\n"); | ||
446 | |||
447 | dev_set_drvdata(dssdev->dev, tpo_td043); | ||
448 | |||
449 | return 0; | ||
450 | |||
451 | fail_gpio_req: | ||
452 | regulator_put(tpo_td043->vcc_reg); | ||
453 | fail_regulator: | ||
454 | kfree(tpo_td043); | ||
455 | return ret; | ||
456 | } | ||
457 | |||
458 | static void tpo_td043_remove(struct omap_dss_device *dssdev) | ||
459 | { | ||
460 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); | ||
461 | |||
462 | dev_dbg(dssdev->dev, "remove\n"); | ||
463 | |||
464 | sysfs_remove_group(&dssdev->dev->kobj, &tpo_td043_attr_group); | ||
465 | regulator_put(tpo_td043->vcc_reg); | ||
466 | } | ||
467 | |||
468 | static void tpo_td043_set_timings(struct omap_dss_device *dssdev, | ||
469 | struct omap_video_timings *timings) | ||
470 | { | ||
471 | omapdss_dpi_set_timings(dssdev, timings); | ||
472 | |||
473 | dssdev->panel.timings = *timings; | ||
474 | } | ||
475 | |||
476 | static int tpo_td043_check_timings(struct omap_dss_device *dssdev, | ||
477 | struct omap_video_timings *timings) | ||
478 | { | ||
479 | return dpi_check_timings(dssdev, timings); | ||
480 | } | ||
481 | |||
482 | static struct omap_dss_driver tpo_td043_driver = { | ||
483 | .probe = tpo_td043_probe, | ||
484 | .remove = tpo_td043_remove, | ||
485 | |||
486 | .enable = tpo_td043_enable, | ||
487 | .disable = tpo_td043_disable, | ||
488 | .set_mirror = tpo_td043_set_hmirror, | ||
489 | .get_mirror = tpo_td043_get_hmirror, | ||
490 | |||
491 | .set_timings = tpo_td043_set_timings, | ||
492 | .check_timings = tpo_td043_check_timings, | ||
493 | |||
494 | .driver = { | ||
495 | .name = "tpo_td043mtea1_panel", | ||
496 | .owner = THIS_MODULE, | ||
497 | }, | ||
498 | }; | ||
499 | |||
500 | static int tpo_td043_spi_probe(struct spi_device *spi) | ||
501 | { | ||
502 | struct omap_dss_device *dssdev = spi->dev.platform_data; | ||
503 | struct tpo_td043_device *tpo_td043; | ||
504 | int ret; | ||
505 | |||
506 | if (dssdev == NULL) { | ||
507 | dev_err(&spi->dev, "missing dssdev\n"); | ||
508 | return -ENODEV; | ||
509 | } | ||
510 | |||
511 | if (g_tpo_td043 != NULL) | ||
512 | return -EBUSY; | ||
513 | |||
514 | spi->bits_per_word = 16; | ||
515 | spi->mode = SPI_MODE_0; | ||
516 | |||
517 | ret = spi_setup(spi); | ||
518 | if (ret < 0) { | ||
519 | dev_err(&spi->dev, "spi_setup failed: %d\n", ret); | ||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL); | ||
524 | if (tpo_td043 == NULL) | ||
525 | return -ENOMEM; | ||
526 | |||
527 | tpo_td043->spi = spi; | ||
528 | dev_set_drvdata(&spi->dev, tpo_td043); | ||
529 | g_tpo_td043 = tpo_td043; | ||
530 | |||
531 | omap_dss_register_driver(&tpo_td043_driver); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int tpo_td043_spi_remove(struct spi_device *spi) | ||
537 | { | ||
538 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev); | ||
539 | |||
540 | omap_dss_unregister_driver(&tpo_td043_driver); | ||
541 | kfree(tpo_td043); | ||
542 | g_tpo_td043 = NULL; | ||
543 | |||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | #ifdef CONFIG_PM_SLEEP | ||
548 | static int tpo_td043_spi_suspend(struct device *dev) | ||
549 | { | ||
550 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
551 | |||
552 | dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043); | ||
553 | |||
554 | tpo_td043->power_on_resume = tpo_td043->powered_on; | ||
555 | tpo_td043_power_off(tpo_td043); | ||
556 | tpo_td043->spi_suspended = 1; | ||
557 | |||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int tpo_td043_spi_resume(struct device *dev) | ||
562 | { | ||
563 | struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); | ||
564 | int ret; | ||
565 | |||
566 | dev_dbg(dev, "tpo_td043_spi_resume\n"); | ||
567 | |||
568 | if (tpo_td043->power_on_resume) { | ||
569 | ret = tpo_td043_power_on(tpo_td043); | ||
570 | if (ret) | ||
571 | return ret; | ||
572 | } | ||
573 | tpo_td043->spi_suspended = 0; | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | #endif | ||
578 | |||
579 | static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm, | ||
580 | tpo_td043_spi_suspend, tpo_td043_spi_resume); | ||
581 | |||
582 | static struct spi_driver tpo_td043_spi_driver = { | ||
583 | .driver = { | ||
584 | .name = "tpo_td043mtea1_panel_spi", | ||
585 | .owner = THIS_MODULE, | ||
586 | .pm = &tpo_td043_spi_pm, | ||
587 | }, | ||
588 | .probe = tpo_td043_spi_probe, | ||
589 | .remove = tpo_td043_spi_remove, | ||
590 | }; | ||
591 | |||
592 | module_spi_driver(tpo_td043_spi_driver); | ||
593 | |||
594 | MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>"); | ||
595 | MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); | ||
596 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index 8f70a8300b84..dde4281663b1 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig | |||
@@ -42,6 +42,7 @@ config OMAP2_DSS_DPI | |||
42 | 42 | ||
43 | config OMAP2_DSS_RFBI | 43 | config OMAP2_DSS_RFBI |
44 | bool "RFBI support" | 44 | bool "RFBI support" |
45 | depends on BROKEN | ||
45 | default n | 46 | default n |
46 | help | 47 | help |
47 | MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas | 48 | MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas |
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index 61949ff7940c..94832eb06a3d 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile | |||
@@ -7,9 +7,8 @@ omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ | |||
7 | dispc-compat.o display-sysfs.o | 7 | dispc-compat.o display-sysfs.o |
8 | omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o | 8 | omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o |
9 | omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o | 9 | omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o |
10 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o | 10 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o |
11 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o | 11 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o |
12 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o | 12 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o |
13 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ | 13 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o ti_hdmi_4xxx_ip.o |
14 | hdmi_panel.o ti_hdmi_4xxx_ip.o | ||
15 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG | 14 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG |
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index d6212d63cfb2..60758dbefd79 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -428,8 +428,8 @@ static struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *m | |||
428 | if (dssdev == NULL) | 428 | if (dssdev == NULL) |
429 | return NULL; | 429 | return NULL; |
430 | 430 | ||
431 | while (dssdev->device) | 431 | while (dssdev->dst) |
432 | dssdev = dssdev->device; | 432 | dssdev = dssdev->dst; |
433 | 433 | ||
434 | if (dssdev->driver) | 434 | if (dssdev->driver) |
435 | return dssdev; | 435 | return dssdev; |
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 1aeb274e30fc..60d3958d04f7 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c | |||
@@ -43,9 +43,6 @@ | |||
43 | static struct { | 43 | static struct { |
44 | struct platform_device *pdev; | 44 | struct platform_device *pdev; |
45 | 45 | ||
46 | struct regulator *vdds_dsi_reg; | ||
47 | struct regulator *vdds_sdi_reg; | ||
48 | |||
49 | const char *default_display_name; | 46 | const char *default_display_name; |
50 | } core; | 47 | } core; |
51 | 48 | ||
@@ -79,36 +76,6 @@ struct platform_device *dss_get_core_pdev(void) | |||
79 | return core.pdev; | 76 | return core.pdev; |
80 | } | 77 | } |
81 | 78 | ||
82 | /* REGULATORS */ | ||
83 | |||
84 | struct regulator *dss_get_vdds_dsi(void) | ||
85 | { | ||
86 | struct regulator *reg; | ||
87 | |||
88 | if (core.vdds_dsi_reg != NULL) | ||
89 | return core.vdds_dsi_reg; | ||
90 | |||
91 | reg = devm_regulator_get(&core.pdev->dev, "vdds_dsi"); | ||
92 | if (!IS_ERR(reg)) | ||
93 | core.vdds_dsi_reg = reg; | ||
94 | |||
95 | return reg; | ||
96 | } | ||
97 | |||
98 | struct regulator *dss_get_vdds_sdi(void) | ||
99 | { | ||
100 | struct regulator *reg; | ||
101 | |||
102 | if (core.vdds_sdi_reg != NULL) | ||
103 | return core.vdds_sdi_reg; | ||
104 | |||
105 | reg = devm_regulator_get(&core.pdev->dev, "vdds_sdi"); | ||
106 | if (!IS_ERR(reg)) | ||
107 | core.vdds_sdi_reg = reg; | ||
108 | |||
109 | return reg; | ||
110 | } | ||
111 | |||
112 | int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask) | 79 | int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask) |
113 | { | 80 | { |
114 | struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; | 81 | struct omap_dss_board_info *board_data = core.pdev->dev.platform_data; |
@@ -189,7 +156,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)) | |||
189 | d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, | 156 | d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, |
190 | write, &dss_debug_fops); | 157 | write, &dss_debug_fops); |
191 | 158 | ||
192 | return PTR_RET(d); | 159 | return PTR_ERR_OR_ZERO(d); |
193 | } | 160 | } |
194 | #else /* CONFIG_OMAP2_DSS_DEBUGFS */ | 161 | #else /* CONFIG_OMAP2_DSS_DEBUGFS */ |
195 | static inline int dss_initialize_debugfs(void) | 162 | static inline int dss_initialize_debugfs(void) |
@@ -281,235 +248,6 @@ static struct platform_driver omap_dss_driver = { | |||
281 | }, | 248 | }, |
282 | }; | 249 | }; |
283 | 250 | ||
284 | /* BUS */ | ||
285 | static int dss_bus_match(struct device *dev, struct device_driver *driver) | ||
286 | { | ||
287 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
288 | |||
289 | DSSDBG("bus_match. dev %s/%s, drv %s\n", | ||
290 | dev_name(dev), dssdev->driver_name, driver->name); | ||
291 | |||
292 | return strcmp(dssdev->driver_name, driver->name) == 0; | ||
293 | } | ||
294 | |||
295 | static struct bus_type dss_bus_type = { | ||
296 | .name = "omapdss", | ||
297 | .match = dss_bus_match, | ||
298 | }; | ||
299 | |||
300 | static void dss_bus_release(struct device *dev) | ||
301 | { | ||
302 | DSSDBG("bus_release\n"); | ||
303 | } | ||
304 | |||
305 | static struct device dss_bus = { | ||
306 | .release = dss_bus_release, | ||
307 | }; | ||
308 | |||
309 | struct bus_type *dss_get_bus(void) | ||
310 | { | ||
311 | return &dss_bus_type; | ||
312 | } | ||
313 | |||
314 | /* DRIVER */ | ||
315 | static int dss_driver_probe(struct device *dev) | ||
316 | { | ||
317 | int r; | ||
318 | struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); | ||
319 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
320 | |||
321 | DSSDBG("driver_probe: dev %s/%s, drv %s\n", | ||
322 | dev_name(dev), dssdev->driver_name, | ||
323 | dssdrv->driver.name); | ||
324 | |||
325 | r = dssdrv->probe(dssdev); | ||
326 | |||
327 | if (r) { | ||
328 | DSSERR("driver probe failed: %d\n", r); | ||
329 | return r; | ||
330 | } | ||
331 | |||
332 | DSSDBG("probe done for device %s\n", dev_name(dev)); | ||
333 | |||
334 | dssdev->driver = dssdrv; | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int dss_driver_remove(struct device *dev) | ||
340 | { | ||
341 | struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); | ||
342 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
343 | |||
344 | DSSDBG("driver_remove: dev %s/%s\n", dev_name(dev), | ||
345 | dssdev->driver_name); | ||
346 | |||
347 | dssdrv->remove(dssdev); | ||
348 | |||
349 | dssdev->driver = NULL; | ||
350 | |||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static int omapdss_default_connect(struct omap_dss_device *dssdev) | ||
355 | { | ||
356 | struct omap_dss_device *out; | ||
357 | struct omap_overlay_manager *mgr; | ||
358 | int r; | ||
359 | |||
360 | out = dssdev->output; | ||
361 | |||
362 | if (out == NULL) | ||
363 | return -ENODEV; | ||
364 | |||
365 | mgr = omap_dss_get_overlay_manager(out->dispc_channel); | ||
366 | if (!mgr) | ||
367 | return -ENODEV; | ||
368 | |||
369 | r = dss_mgr_connect(mgr, out); | ||
370 | if (r) | ||
371 | return r; | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static void omapdss_default_disconnect(struct omap_dss_device *dssdev) | ||
377 | { | ||
378 | struct omap_dss_device *out; | ||
379 | struct omap_overlay_manager *mgr; | ||
380 | |||
381 | out = dssdev->output; | ||
382 | |||
383 | if (out == NULL) | ||
384 | return; | ||
385 | |||
386 | mgr = out->manager; | ||
387 | |||
388 | if (mgr == NULL) | ||
389 | return; | ||
390 | |||
391 | dss_mgr_disconnect(mgr, out); | ||
392 | } | ||
393 | |||
394 | int omap_dss_register_driver(struct omap_dss_driver *dssdriver) | ||
395 | { | ||
396 | dssdriver->driver.bus = &dss_bus_type; | ||
397 | dssdriver->driver.probe = dss_driver_probe; | ||
398 | dssdriver->driver.remove = dss_driver_remove; | ||
399 | |||
400 | if (dssdriver->get_resolution == NULL) | ||
401 | dssdriver->get_resolution = omapdss_default_get_resolution; | ||
402 | if (dssdriver->get_recommended_bpp == NULL) | ||
403 | dssdriver->get_recommended_bpp = | ||
404 | omapdss_default_get_recommended_bpp; | ||
405 | if (dssdriver->get_timings == NULL) | ||
406 | dssdriver->get_timings = omapdss_default_get_timings; | ||
407 | if (dssdriver->connect == NULL) | ||
408 | dssdriver->connect = omapdss_default_connect; | ||
409 | if (dssdriver->disconnect == NULL) | ||
410 | dssdriver->disconnect = omapdss_default_disconnect; | ||
411 | |||
412 | return driver_register(&dssdriver->driver); | ||
413 | } | ||
414 | EXPORT_SYMBOL(omap_dss_register_driver); | ||
415 | |||
416 | void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver) | ||
417 | { | ||
418 | driver_unregister(&dssdriver->driver); | ||
419 | } | ||
420 | EXPORT_SYMBOL(omap_dss_unregister_driver); | ||
421 | |||
422 | /* DEVICE */ | ||
423 | |||
424 | static void omap_dss_dev_release(struct device *dev) | ||
425 | { | ||
426 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
427 | kfree(dssdev); | ||
428 | } | ||
429 | |||
430 | static int disp_num_counter; | ||
431 | |||
432 | struct omap_dss_device *dss_alloc_and_init_device(struct device *parent) | ||
433 | { | ||
434 | struct omap_dss_device *dssdev; | ||
435 | |||
436 | dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL); | ||
437 | if (!dssdev) | ||
438 | return NULL; | ||
439 | |||
440 | dssdev->old_dev.bus = &dss_bus_type; | ||
441 | dssdev->old_dev.parent = parent; | ||
442 | dssdev->old_dev.release = omap_dss_dev_release; | ||
443 | dev_set_name(&dssdev->old_dev, "display%d", disp_num_counter++); | ||
444 | |||
445 | device_initialize(&dssdev->old_dev); | ||
446 | |||
447 | return dssdev; | ||
448 | } | ||
449 | |||
450 | int dss_add_device(struct omap_dss_device *dssdev) | ||
451 | { | ||
452 | dssdev->dev = &dssdev->old_dev; | ||
453 | |||
454 | omapdss_register_display(dssdev); | ||
455 | return device_add(&dssdev->old_dev); | ||
456 | } | ||
457 | |||
458 | void dss_put_device(struct omap_dss_device *dssdev) | ||
459 | { | ||
460 | put_device(&dssdev->old_dev); | ||
461 | } | ||
462 | |||
463 | void dss_unregister_device(struct omap_dss_device *dssdev) | ||
464 | { | ||
465 | device_unregister(&dssdev->old_dev); | ||
466 | omapdss_unregister_display(dssdev); | ||
467 | } | ||
468 | |||
469 | static int dss_unregister_dss_dev(struct device *dev, void *data) | ||
470 | { | ||
471 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
472 | dss_unregister_device(dssdev); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | void dss_unregister_child_devices(struct device *parent) | ||
477 | { | ||
478 | device_for_each_child(parent, NULL, dss_unregister_dss_dev); | ||
479 | } | ||
480 | |||
481 | void dss_copy_device_pdata(struct omap_dss_device *dst, | ||
482 | const struct omap_dss_device *src) | ||
483 | { | ||
484 | u8 *d = (u8 *)dst; | ||
485 | u8 *s = (u8 *)src; | ||
486 | size_t dsize = sizeof(struct device); | ||
487 | |||
488 | memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize); | ||
489 | } | ||
490 | |||
491 | /* BUS */ | ||
492 | static int __init omap_dss_bus_register(void) | ||
493 | { | ||
494 | int r; | ||
495 | |||
496 | r = bus_register(&dss_bus_type); | ||
497 | if (r) { | ||
498 | DSSERR("bus register failed\n"); | ||
499 | return r; | ||
500 | } | ||
501 | |||
502 | dev_set_name(&dss_bus, "omapdss"); | ||
503 | r = device_register(&dss_bus); | ||
504 | if (r) { | ||
505 | DSSERR("bus driver register failed\n"); | ||
506 | bus_unregister(&dss_bus_type); | ||
507 | return r; | ||
508 | } | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | /* INIT */ | 251 | /* INIT */ |
514 | static int (*dss_output_drv_reg_funcs[])(void) __initdata = { | 252 | static int (*dss_output_drv_reg_funcs[])(void) __initdata = { |
515 | #ifdef CONFIG_OMAP2_DSS_DSI | 253 | #ifdef CONFIG_OMAP2_DSS_DSI |
@@ -555,7 +293,7 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { | |||
555 | 293 | ||
556 | static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; | 294 | static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; |
557 | 295 | ||
558 | static int __init omap_dss_register_drivers(void) | 296 | static int __init omap_dss_init(void) |
559 | { | 297 | { |
560 | int r; | 298 | int r; |
561 | int i; | 299 | int i; |
@@ -586,6 +324,8 @@ static int __init omap_dss_register_drivers(void) | |||
586 | dss_output_drv_loaded[i] = true; | 324 | dss_output_drv_loaded[i] = true; |
587 | } | 325 | } |
588 | 326 | ||
327 | dss_initialized = true; | ||
328 | |||
589 | return 0; | 329 | return 0; |
590 | 330 | ||
591 | err_dispc: | 331 | err_dispc: |
@@ -596,7 +336,7 @@ err_dss: | |||
596 | return r; | 336 | return r; |
597 | } | 337 | } |
598 | 338 | ||
599 | static void __exit omap_dss_unregister_drivers(void) | 339 | static void __exit omap_dss_exit(void) |
600 | { | 340 | { |
601 | int i; | 341 | int i; |
602 | 342 | ||
@@ -611,64 +351,8 @@ static void __exit omap_dss_unregister_drivers(void) | |||
611 | platform_driver_unregister(&omap_dss_driver); | 351 | platform_driver_unregister(&omap_dss_driver); |
612 | } | 352 | } |
613 | 353 | ||
614 | #ifdef CONFIG_OMAP2_DSS_MODULE | ||
615 | static void omap_dss_bus_unregister(void) | ||
616 | { | ||
617 | device_unregister(&dss_bus); | ||
618 | |||
619 | bus_unregister(&dss_bus_type); | ||
620 | } | ||
621 | |||
622 | static int __init omap_dss_init(void) | ||
623 | { | ||
624 | int r; | ||
625 | |||
626 | r = omap_dss_bus_register(); | ||
627 | if (r) | ||
628 | return r; | ||
629 | |||
630 | r = omap_dss_register_drivers(); | ||
631 | if (r) { | ||
632 | omap_dss_bus_unregister(); | ||
633 | return r; | ||
634 | } | ||
635 | |||
636 | dss_initialized = true; | ||
637 | |||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | static void __exit omap_dss_exit(void) | ||
642 | { | ||
643 | omap_dss_unregister_drivers(); | ||
644 | |||
645 | omap_dss_bus_unregister(); | ||
646 | } | ||
647 | |||
648 | module_init(omap_dss_init); | 354 | module_init(omap_dss_init); |
649 | module_exit(omap_dss_exit); | 355 | module_exit(omap_dss_exit); |
650 | #else | ||
651 | static int __init omap_dss_init(void) | ||
652 | { | ||
653 | return omap_dss_bus_register(); | ||
654 | } | ||
655 | |||
656 | static int __init omap_dss_init2(void) | ||
657 | { | ||
658 | int r; | ||
659 | |||
660 | r = omap_dss_register_drivers(); | ||
661 | if (r) | ||
662 | return r; | ||
663 | |||
664 | dss_initialized = true; | ||
665 | |||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | core_initcall(omap_dss_init); | ||
670 | device_initcall(omap_dss_init2); | ||
671 | #endif | ||
672 | 356 | ||
673 | MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); | 357 | MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); |
674 | MODULE_DESCRIPTION("OMAP2/3 Display Subsystem"); | 358 | MODULE_DESCRIPTION("OMAP2/3 Display Subsystem"); |
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index a6b331ef7763..bd48cde53561 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c | |||
@@ -345,7 +345,7 @@ static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr) | |||
345 | dss_mgr_set_lcd_config(mgr, &dpi.mgr_config); | 345 | dss_mgr_set_lcd_config(mgr, &dpi.mgr_config); |
346 | } | 346 | } |
347 | 347 | ||
348 | int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | 348 | static int dpi_display_enable(struct omap_dss_device *dssdev) |
349 | { | 349 | { |
350 | struct omap_dss_device *out = &dpi.output; | 350 | struct omap_dss_device *out = &dpi.output; |
351 | int r; | 351 | int r; |
@@ -423,9 +423,8 @@ err_no_reg: | |||
423 | mutex_unlock(&dpi.lock); | 423 | mutex_unlock(&dpi.lock); |
424 | return r; | 424 | return r; |
425 | } | 425 | } |
426 | EXPORT_SYMBOL(omapdss_dpi_display_enable); | ||
427 | 426 | ||
428 | void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) | 427 | static void dpi_display_disable(struct omap_dss_device *dssdev) |
429 | { | 428 | { |
430 | struct omap_overlay_manager *mgr = dpi.output.manager; | 429 | struct omap_overlay_manager *mgr = dpi.output.manager; |
431 | 430 | ||
@@ -446,9 +445,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) | |||
446 | 445 | ||
447 | mutex_unlock(&dpi.lock); | 446 | mutex_unlock(&dpi.lock); |
448 | } | 447 | } |
449 | EXPORT_SYMBOL(omapdss_dpi_display_disable); | ||
450 | 448 | ||
451 | void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, | 449 | static void dpi_set_timings(struct omap_dss_device *dssdev, |
452 | struct omap_video_timings *timings) | 450 | struct omap_video_timings *timings) |
453 | { | 451 | { |
454 | DSSDBG("dpi_set_timings\n"); | 452 | DSSDBG("dpi_set_timings\n"); |
@@ -459,7 +457,6 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, | |||
459 | 457 | ||
460 | mutex_unlock(&dpi.lock); | 458 | mutex_unlock(&dpi.lock); |
461 | } | 459 | } |
462 | EXPORT_SYMBOL(omapdss_dpi_set_timings); | ||
463 | 460 | ||
464 | static void dpi_get_timings(struct omap_dss_device *dssdev, | 461 | static void dpi_get_timings(struct omap_dss_device *dssdev, |
465 | struct omap_video_timings *timings) | 462 | struct omap_video_timings *timings) |
@@ -471,7 +468,7 @@ static void dpi_get_timings(struct omap_dss_device *dssdev, | |||
471 | mutex_unlock(&dpi.lock); | 468 | mutex_unlock(&dpi.lock); |
472 | } | 469 | } |
473 | 470 | ||
474 | int dpi_check_timings(struct omap_dss_device *dssdev, | 471 | static int dpi_check_timings(struct omap_dss_device *dssdev, |
475 | struct omap_video_timings *timings) | 472 | struct omap_video_timings *timings) |
476 | { | 473 | { |
477 | struct omap_overlay_manager *mgr = dpi.output.manager; | 474 | struct omap_overlay_manager *mgr = dpi.output.manager; |
@@ -510,9 +507,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev, | |||
510 | 507 | ||
511 | return 0; | 508 | return 0; |
512 | } | 509 | } |
513 | EXPORT_SYMBOL(dpi_check_timings); | ||
514 | 510 | ||
515 | void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) | 511 | static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) |
516 | { | 512 | { |
517 | mutex_lock(&dpi.lock); | 513 | mutex_lock(&dpi.lock); |
518 | 514 | ||
@@ -520,7 +516,6 @@ void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) | |||
520 | 516 | ||
521 | mutex_unlock(&dpi.lock); | 517 | mutex_unlock(&dpi.lock); |
522 | } | 518 | } |
523 | EXPORT_SYMBOL(omapdss_dpi_set_data_lines); | ||
524 | 519 | ||
525 | static int dpi_verify_dsi_pll(struct platform_device *dsidev) | 520 | static int dpi_verify_dsi_pll(struct platform_device *dsidev) |
526 | { | 521 | { |
@@ -554,14 +549,10 @@ static int dpi_init_regulator(void) | |||
554 | if (dpi.vdds_dsi_reg) | 549 | if (dpi.vdds_dsi_reg) |
555 | return 0; | 550 | return 0; |
556 | 551 | ||
557 | vdds_dsi = dss_get_vdds_dsi(); | 552 | vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); |
558 | |||
559 | if (IS_ERR(vdds_dsi)) { | 553 | if (IS_ERR(vdds_dsi)) { |
560 | vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); | 554 | DSSERR("can't get VDDS_DSI regulator\n"); |
561 | if (IS_ERR(vdds_dsi)) { | 555 | return PTR_ERR(vdds_dsi); |
562 | DSSERR("can't get VDDS_DSI regulator\n"); | ||
563 | return PTR_ERR(vdds_dsi); | ||
564 | } | ||
565 | } | 556 | } |
566 | 557 | ||
567 | dpi.vdds_dsi_reg = vdds_dsi; | 558 | dpi.vdds_dsi_reg = vdds_dsi; |
@@ -618,76 +609,6 @@ static enum omap_channel dpi_get_channel(void) | |||
618 | } | 609 | } |
619 | } | 610 | } |
620 | 611 | ||
621 | static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev) | ||
622 | { | ||
623 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
624 | const char *def_disp_name = omapdss_get_default_display_name(); | ||
625 | struct omap_dss_device *def_dssdev; | ||
626 | int i; | ||
627 | |||
628 | def_dssdev = NULL; | ||
629 | |||
630 | for (i = 0; i < pdata->num_devices; ++i) { | ||
631 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
632 | |||
633 | if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) | ||
634 | continue; | ||
635 | |||
636 | if (def_dssdev == NULL) | ||
637 | def_dssdev = dssdev; | ||
638 | |||
639 | if (def_disp_name != NULL && | ||
640 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
641 | def_dssdev = dssdev; | ||
642 | break; | ||
643 | } | ||
644 | } | ||
645 | |||
646 | return def_dssdev; | ||
647 | } | ||
648 | |||
649 | static int dpi_probe_pdata(struct platform_device *dpidev) | ||
650 | { | ||
651 | struct omap_dss_device *plat_dssdev; | ||
652 | struct omap_dss_device *dssdev; | ||
653 | int r; | ||
654 | |||
655 | plat_dssdev = dpi_find_dssdev(dpidev); | ||
656 | |||
657 | if (!plat_dssdev) | ||
658 | return 0; | ||
659 | |||
660 | r = dpi_init_regulator(); | ||
661 | if (r) | ||
662 | return r; | ||
663 | |||
664 | dpi_init_pll(); | ||
665 | |||
666 | dssdev = dss_alloc_and_init_device(&dpidev->dev); | ||
667 | if (!dssdev) | ||
668 | return -ENOMEM; | ||
669 | |||
670 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
671 | |||
672 | r = omapdss_output_set_device(&dpi.output, dssdev); | ||
673 | if (r) { | ||
674 | DSSERR("failed to connect output to new device: %s\n", | ||
675 | dssdev->name); | ||
676 | dss_put_device(dssdev); | ||
677 | return r; | ||
678 | } | ||
679 | |||
680 | r = dss_add_device(dssdev); | ||
681 | if (r) { | ||
682 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
683 | omapdss_output_unset_device(&dpi.output); | ||
684 | dss_put_device(dssdev); | ||
685 | return r; | ||
686 | } | ||
687 | |||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | static int dpi_connect(struct omap_dss_device *dssdev, | 612 | static int dpi_connect(struct omap_dss_device *dssdev, |
692 | struct omap_dss_device *dst) | 613 | struct omap_dss_device *dst) |
693 | { | 614 | { |
@@ -722,9 +643,9 @@ static int dpi_connect(struct omap_dss_device *dssdev, | |||
722 | static void dpi_disconnect(struct omap_dss_device *dssdev, | 643 | static void dpi_disconnect(struct omap_dss_device *dssdev, |
723 | struct omap_dss_device *dst) | 644 | struct omap_dss_device *dst) |
724 | { | 645 | { |
725 | WARN_ON(dst != dssdev->device); | 646 | WARN_ON(dst != dssdev->dst); |
726 | 647 | ||
727 | if (dst != dssdev->device) | 648 | if (dst != dssdev->dst) |
728 | return; | 649 | return; |
729 | 650 | ||
730 | omapdss_output_unset_device(dssdev); | 651 | omapdss_output_unset_device(dssdev); |
@@ -737,14 +658,14 @@ static const struct omapdss_dpi_ops dpi_ops = { | |||
737 | .connect = dpi_connect, | 658 | .connect = dpi_connect, |
738 | .disconnect = dpi_disconnect, | 659 | .disconnect = dpi_disconnect, |
739 | 660 | ||
740 | .enable = omapdss_dpi_display_enable, | 661 | .enable = dpi_display_enable, |
741 | .disable = omapdss_dpi_display_disable, | 662 | .disable = dpi_display_disable, |
742 | 663 | ||
743 | .check_timings = dpi_check_timings, | 664 | .check_timings = dpi_check_timings, |
744 | .set_timings = omapdss_dpi_set_timings, | 665 | .set_timings = dpi_set_timings, |
745 | .get_timings = dpi_get_timings, | 666 | .get_timings = dpi_get_timings, |
746 | 667 | ||
747 | .set_data_lines = omapdss_dpi_set_data_lines, | 668 | .set_data_lines = dpi_set_data_lines, |
748 | }; | 669 | }; |
749 | 670 | ||
750 | static void dpi_init_output(struct platform_device *pdev) | 671 | static void dpi_init_output(struct platform_device *pdev) |
@@ -771,31 +692,17 @@ static void __exit dpi_uninit_output(struct platform_device *pdev) | |||
771 | 692 | ||
772 | static int omap_dpi_probe(struct platform_device *pdev) | 693 | static int omap_dpi_probe(struct platform_device *pdev) |
773 | { | 694 | { |
774 | int r; | ||
775 | |||
776 | dpi.pdev = pdev; | 695 | dpi.pdev = pdev; |
777 | 696 | ||
778 | mutex_init(&dpi.lock); | 697 | mutex_init(&dpi.lock); |
779 | 698 | ||
780 | dpi_init_output(pdev); | 699 | dpi_init_output(pdev); |
781 | 700 | ||
782 | if (pdev->dev.platform_data) { | ||
783 | r = dpi_probe_pdata(pdev); | ||
784 | if (r) | ||
785 | goto err_probe; | ||
786 | } | ||
787 | |||
788 | return 0; | 701 | return 0; |
789 | |||
790 | err_probe: | ||
791 | dpi_uninit_output(pdev); | ||
792 | return r; | ||
793 | } | 702 | } |
794 | 703 | ||
795 | static int __exit omap_dpi_remove(struct platform_device *pdev) | 704 | static int __exit omap_dpi_remove(struct platform_device *pdev) |
796 | { | 705 | { |
797 | dss_unregister_child_devices(&pdev->dev); | ||
798 | |||
799 | dpi_uninit_output(pdev); | 706 | dpi_uninit_output(pdev); |
800 | 707 | ||
801 | return 0; | 708 | return 0; |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 99a043b08f0d..a598b5812285 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -205,6 +205,8 @@ static int dsi_display_init_dispc(struct platform_device *dsidev, | |||
205 | static void dsi_display_uninit_dispc(struct platform_device *dsidev, | 205 | static void dsi_display_uninit_dispc(struct platform_device *dsidev, |
206 | struct omap_overlay_manager *mgr); | 206 | struct omap_overlay_manager *mgr); |
207 | 207 | ||
208 | static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); | ||
209 | |||
208 | #define DSI_MAX_NR_ISRS 2 | 210 | #define DSI_MAX_NR_ISRS 2 |
209 | #define DSI_MAX_NR_LANES 5 | 211 | #define DSI_MAX_NR_LANES 5 |
210 | 212 | ||
@@ -383,16 +385,7 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside | |||
383 | 385 | ||
384 | static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) | 386 | static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) |
385 | { | 387 | { |
386 | /* HACK: dssdev can be either the panel device, when using old API, or | 388 | return to_platform_device(dssdev->dev); |
387 | * the dsi device itself, when using the new API. So we solve this for | ||
388 | * now by checking the dssdev->id. This will be removed when the old API | ||
389 | * is removed. | ||
390 | */ | ||
391 | if (dssdev->id == OMAP_DSS_OUTPUT_DSI1 || | ||
392 | dssdev->id == OMAP_DSS_OUTPUT_DSI2) | ||
393 | return to_platform_device(dssdev->dev); | ||
394 | |||
395 | return to_platform_device(dssdev->output->dev); | ||
396 | } | 389 | } |
397 | 390 | ||
398 | struct platform_device *dsi_get_dsidev_from_id(int module) | 391 | struct platform_device *dsi_get_dsidev_from_id(int module) |
@@ -432,23 +425,21 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev, | |||
432 | return __raw_readl(dsi->base + idx.idx); | 425 | return __raw_readl(dsi->base + idx.idx); |
433 | } | 426 | } |
434 | 427 | ||
435 | void dsi_bus_lock(struct omap_dss_device *dssdev) | 428 | static void dsi_bus_lock(struct omap_dss_device *dssdev) |
436 | { | 429 | { |
437 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 430 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
438 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 431 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
439 | 432 | ||
440 | down(&dsi->bus_lock); | 433 | down(&dsi->bus_lock); |
441 | } | 434 | } |
442 | EXPORT_SYMBOL(dsi_bus_lock); | ||
443 | 435 | ||
444 | void dsi_bus_unlock(struct omap_dss_device *dssdev) | 436 | static void dsi_bus_unlock(struct omap_dss_device *dssdev) |
445 | { | 437 | { |
446 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 438 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
447 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 439 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
448 | 440 | ||
449 | up(&dsi->bus_lock); | 441 | up(&dsi->bus_lock); |
450 | } | 442 | } |
451 | EXPORT_SYMBOL(dsi_bus_unlock); | ||
452 | 443 | ||
453 | static bool dsi_bus_is_locked(struct platform_device *dsidev) | 444 | static bool dsi_bus_is_locked(struct platform_device *dsidev) |
454 | { | 445 | { |
@@ -2713,7 +2704,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel, | |||
2713 | return 0; | 2704 | return 0; |
2714 | } | 2705 | } |
2715 | 2706 | ||
2716 | void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | 2707 | static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, |
2717 | bool enable) | 2708 | bool enable) |
2718 | { | 2709 | { |
2719 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 2710 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -2737,7 +2728,6 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | |||
2737 | if (dsi->vm_timings.ddr_clk_always_on && enable) | 2728 | if (dsi->vm_timings.ddr_clk_always_on && enable) |
2738 | dsi_vc_send_null(dssdev, channel); | 2729 | dsi_vc_send_null(dssdev, channel); |
2739 | } | 2730 | } |
2740 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); | ||
2741 | 2731 | ||
2742 | static void dsi_vc_flush_long_data(struct platform_device *dsidev, int channel) | 2732 | static void dsi_vc_flush_long_data(struct platform_device *dsidev, int channel) |
2743 | { | 2733 | { |
@@ -2842,7 +2832,7 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel) | |||
2842 | return 0; | 2832 | return 0; |
2843 | } | 2833 | } |
2844 | 2834 | ||
2845 | int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel) | 2835 | static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel) |
2846 | { | 2836 | { |
2847 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 2837 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
2848 | DECLARE_COMPLETION_ONSTACK(completion); | 2838 | DECLARE_COMPLETION_ONSTACK(completion); |
@@ -2885,7 +2875,6 @@ err1: | |||
2885 | err0: | 2875 | err0: |
2886 | return r; | 2876 | return r; |
2887 | } | 2877 | } |
2888 | EXPORT_SYMBOL(dsi_vc_send_bta_sync); | ||
2889 | 2878 | ||
2890 | static inline void dsi_vc_write_long_header(struct platform_device *dsidev, | 2879 | static inline void dsi_vc_write_long_header(struct platform_device *dsidev, |
2891 | int channel, u8 data_type, u16 len, u8 ecc) | 2880 | int channel, u8 data_type, u16 len, u8 ecc) |
@@ -3011,14 +3000,13 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel, | |||
3011 | return 0; | 3000 | return 0; |
3012 | } | 3001 | } |
3013 | 3002 | ||
3014 | int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) | 3003 | static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) |
3015 | { | 3004 | { |
3016 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3005 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3017 | 3006 | ||
3018 | return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL, | 3007 | return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL, |
3019 | 0, 0); | 3008 | 0, 0); |
3020 | } | 3009 | } |
3021 | EXPORT_SYMBOL(dsi_vc_send_null); | ||
3022 | 3010 | ||
3023 | static int dsi_vc_write_nosync_common(struct platform_device *dsidev, | 3011 | static int dsi_vc_write_nosync_common(struct platform_device *dsidev, |
3024 | int channel, u8 *data, int len, enum dss_dsi_content_type type) | 3012 | int channel, u8 *data, int len, enum dss_dsi_content_type type) |
@@ -3050,7 +3038,7 @@ static int dsi_vc_write_nosync_common(struct platform_device *dsidev, | |||
3050 | return r; | 3038 | return r; |
3051 | } | 3039 | } |
3052 | 3040 | ||
3053 | int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, | 3041 | static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, |
3054 | u8 *data, int len) | 3042 | u8 *data, int len) |
3055 | { | 3043 | { |
3056 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3044 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -3058,9 +3046,8 @@ int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, | |||
3058 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, | 3046 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, |
3059 | DSS_DSI_CONTENT_DCS); | 3047 | DSS_DSI_CONTENT_DCS); |
3060 | } | 3048 | } |
3061 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); | ||
3062 | 3049 | ||
3063 | int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, | 3050 | static int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, |
3064 | u8 *data, int len) | 3051 | u8 *data, int len) |
3065 | { | 3052 | { |
3066 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3053 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -3068,7 +3055,6 @@ int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, | |||
3068 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, | 3055 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, |
3069 | DSS_DSI_CONTENT_GENERIC); | 3056 | DSS_DSI_CONTENT_GENERIC); |
3070 | } | 3057 | } |
3071 | EXPORT_SYMBOL(dsi_vc_generic_write_nosync); | ||
3072 | 3058 | ||
3073 | static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel, | 3059 | static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel, |
3074 | u8 *data, int len, enum dss_dsi_content_type type) | 3060 | u8 *data, int len, enum dss_dsi_content_type type) |
@@ -3099,60 +3085,19 @@ err: | |||
3099 | return r; | 3085 | return r; |
3100 | } | 3086 | } |
3101 | 3087 | ||
3102 | int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data, | 3088 | static int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data, |
3103 | int len) | 3089 | int len) |
3104 | { | 3090 | { |
3105 | return dsi_vc_write_common(dssdev, channel, data, len, | 3091 | return dsi_vc_write_common(dssdev, channel, data, len, |
3106 | DSS_DSI_CONTENT_DCS); | 3092 | DSS_DSI_CONTENT_DCS); |
3107 | } | 3093 | } |
3108 | EXPORT_SYMBOL(dsi_vc_dcs_write); | ||
3109 | 3094 | ||
3110 | int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data, | 3095 | static int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data, |
3111 | int len) | 3096 | int len) |
3112 | { | 3097 | { |
3113 | return dsi_vc_write_common(dssdev, channel, data, len, | 3098 | return dsi_vc_write_common(dssdev, channel, data, len, |
3114 | DSS_DSI_CONTENT_GENERIC); | 3099 | DSS_DSI_CONTENT_GENERIC); |
3115 | } | 3100 | } |
3116 | EXPORT_SYMBOL(dsi_vc_generic_write); | ||
3117 | |||
3118 | int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd) | ||
3119 | { | ||
3120 | return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1); | ||
3121 | } | ||
3122 | EXPORT_SYMBOL(dsi_vc_dcs_write_0); | ||
3123 | |||
3124 | int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel) | ||
3125 | { | ||
3126 | return dsi_vc_generic_write(dssdev, channel, NULL, 0); | ||
3127 | } | ||
3128 | EXPORT_SYMBOL(dsi_vc_generic_write_0); | ||
3129 | |||
3130 | int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | ||
3131 | u8 param) | ||
3132 | { | ||
3133 | u8 buf[2]; | ||
3134 | buf[0] = dcs_cmd; | ||
3135 | buf[1] = param; | ||
3136 | return dsi_vc_dcs_write(dssdev, channel, buf, 2); | ||
3137 | } | ||
3138 | EXPORT_SYMBOL(dsi_vc_dcs_write_1); | ||
3139 | |||
3140 | int dsi_vc_generic_write_1(struct omap_dss_device *dssdev, int channel, | ||
3141 | u8 param) | ||
3142 | { | ||
3143 | return dsi_vc_generic_write(dssdev, channel, ¶m, 1); | ||
3144 | } | ||
3145 | EXPORT_SYMBOL(dsi_vc_generic_write_1); | ||
3146 | |||
3147 | int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel, | ||
3148 | u8 param1, u8 param2) | ||
3149 | { | ||
3150 | u8 buf[2]; | ||
3151 | buf[0] = param1; | ||
3152 | buf[1] = param2; | ||
3153 | return dsi_vc_generic_write(dssdev, channel, buf, 2); | ||
3154 | } | ||
3155 | EXPORT_SYMBOL(dsi_vc_generic_write_2); | ||
3156 | 3101 | ||
3157 | static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev, | 3102 | static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev, |
3158 | int channel, u8 dcs_cmd) | 3103 | int channel, u8 dcs_cmd) |
@@ -3319,7 +3264,7 @@ err: | |||
3319 | return r; | 3264 | return r; |
3320 | } | 3265 | } |
3321 | 3266 | ||
3322 | int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | 3267 | static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, |
3323 | u8 *buf, int buflen) | 3268 | u8 *buf, int buflen) |
3324 | { | 3269 | { |
3325 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3270 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -3348,7 +3293,6 @@ err: | |||
3348 | DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", channel, dcs_cmd); | 3293 | DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", channel, dcs_cmd); |
3349 | return r; | 3294 | return r; |
3350 | } | 3295 | } |
3351 | EXPORT_SYMBOL(dsi_vc_dcs_read); | ||
3352 | 3296 | ||
3353 | static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel, | 3297 | static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel, |
3354 | u8 *reqdata, int reqlen, u8 *buf, int buflen) | 3298 | u8 *reqdata, int reqlen, u8 *buf, int buflen) |
@@ -3377,56 +3321,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel, | |||
3377 | return 0; | 3321 | return 0; |
3378 | } | 3322 | } |
3379 | 3323 | ||
3380 | int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf, | 3324 | static int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, |
3381 | int buflen) | ||
3382 | { | ||
3383 | int r; | ||
3384 | |||
3385 | r = dsi_vc_generic_read(dssdev, channel, NULL, 0, buf, buflen); | ||
3386 | if (r) { | ||
3387 | DSSERR("dsi_vc_generic_read_0(ch %d) failed\n", channel); | ||
3388 | return r; | ||
3389 | } | ||
3390 | |||
3391 | return 0; | ||
3392 | } | ||
3393 | EXPORT_SYMBOL(dsi_vc_generic_read_0); | ||
3394 | |||
3395 | int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param, | ||
3396 | u8 *buf, int buflen) | ||
3397 | { | ||
3398 | int r; | ||
3399 | |||
3400 | r = dsi_vc_generic_read(dssdev, channel, ¶m, 1, buf, buflen); | ||
3401 | if (r) { | ||
3402 | DSSERR("dsi_vc_generic_read_1(ch %d) failed\n", channel); | ||
3403 | return r; | ||
3404 | } | ||
3405 | |||
3406 | return 0; | ||
3407 | } | ||
3408 | EXPORT_SYMBOL(dsi_vc_generic_read_1); | ||
3409 | |||
3410 | int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel, | ||
3411 | u8 param1, u8 param2, u8 *buf, int buflen) | ||
3412 | { | ||
3413 | int r; | ||
3414 | u8 reqdata[2]; | ||
3415 | |||
3416 | reqdata[0] = param1; | ||
3417 | reqdata[1] = param2; | ||
3418 | |||
3419 | r = dsi_vc_generic_read(dssdev, channel, reqdata, 2, buf, buflen); | ||
3420 | if (r) { | ||
3421 | DSSERR("dsi_vc_generic_read_2(ch %d) failed\n", channel); | ||
3422 | return r; | ||
3423 | } | ||
3424 | |||
3425 | return 0; | ||
3426 | } | ||
3427 | EXPORT_SYMBOL(dsi_vc_generic_read_2); | ||
3428 | |||
3429 | int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, | ||
3430 | u16 len) | 3325 | u16 len) |
3431 | { | 3326 | { |
3432 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3327 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -3434,7 +3329,6 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, | |||
3434 | return dsi_vc_send_short(dsidev, channel, | 3329 | return dsi_vc_send_short(dsidev, channel, |
3435 | MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0); | 3330 | MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0); |
3436 | } | 3331 | } |
3437 | EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); | ||
3438 | 3332 | ||
3439 | static int dsi_enter_ulps(struct platform_device *dsidev) | 3333 | static int dsi_enter_ulps(struct platform_device *dsidev) |
3440 | { | 3334 | { |
@@ -4068,7 +3962,7 @@ static void dsi_proto_timings(struct platform_device *dsidev) | |||
4068 | } | 3962 | } |
4069 | } | 3963 | } |
4070 | 3964 | ||
4071 | int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, | 3965 | static int dsi_configure_pins(struct omap_dss_device *dssdev, |
4072 | const struct omap_dsi_pin_config *pin_cfg) | 3966 | const struct omap_dsi_pin_config *pin_cfg) |
4073 | { | 3967 | { |
4074 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3968 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -4134,9 +4028,8 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, | |||
4134 | 4028 | ||
4135 | return 0; | 4029 | return 0; |
4136 | } | 4030 | } |
4137 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); | ||
4138 | 4031 | ||
4139 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | 4032 | static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) |
4140 | { | 4033 | { |
4141 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4034 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4142 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4035 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -4206,9 +4099,8 @@ err_pix_fmt: | |||
4206 | err_init_dispc: | 4099 | err_init_dispc: |
4207 | return r; | 4100 | return r; |
4208 | } | 4101 | } |
4209 | EXPORT_SYMBOL(dsi_enable_video_output); | ||
4210 | 4102 | ||
4211 | void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) | 4103 | static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) |
4212 | { | 4104 | { |
4213 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4105 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4214 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4106 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -4229,7 +4121,6 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) | |||
4229 | 4121 | ||
4230 | dsi_display_uninit_dispc(dsidev, mgr); | 4122 | dsi_display_uninit_dispc(dsidev, mgr); |
4231 | } | 4123 | } |
4232 | EXPORT_SYMBOL(dsi_disable_video_output); | ||
4233 | 4124 | ||
4234 | static void dsi_update_screen_dispc(struct platform_device *dsidev) | 4125 | static void dsi_update_screen_dispc(struct platform_device *dsidev) |
4235 | { | 4126 | { |
@@ -4369,7 +4260,7 @@ static void dsi_framedone_irq_callback(void *data) | |||
4369 | dsi_handle_framedone(dsidev, 0); | 4260 | dsi_handle_framedone(dsidev, 0); |
4370 | } | 4261 | } |
4371 | 4262 | ||
4372 | int omap_dsi_update(struct omap_dss_device *dssdev, int channel, | 4263 | static int dsi_update(struct omap_dss_device *dssdev, int channel, |
4373 | void (*callback)(int, void *), void *data) | 4264 | void (*callback)(int, void *), void *data) |
4374 | { | 4265 | { |
4375 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4266 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -4394,7 +4285,6 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel, | |||
4394 | 4285 | ||
4395 | return 0; | 4286 | return 0; |
4396 | } | 4287 | } |
4397 | EXPORT_SYMBOL(omap_dsi_update); | ||
4398 | 4288 | ||
4399 | /* Display funcs */ | 4289 | /* Display funcs */ |
4400 | 4290 | ||
@@ -4589,7 +4479,7 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev, | |||
4589 | dsi_pll_uninit(dsidev, disconnect_lanes); | 4479 | dsi_pll_uninit(dsidev, disconnect_lanes); |
4590 | } | 4480 | } |
4591 | 4481 | ||
4592 | int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | 4482 | static int dsi_display_enable(struct omap_dss_device *dssdev) |
4593 | { | 4483 | { |
4594 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4484 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4595 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4485 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -4625,9 +4515,8 @@ err_get_dsi: | |||
4625 | DSSDBG("dsi_display_enable FAILED\n"); | 4515 | DSSDBG("dsi_display_enable FAILED\n"); |
4626 | return r; | 4516 | return r; |
4627 | } | 4517 | } |
4628 | EXPORT_SYMBOL(omapdss_dsi_display_enable); | ||
4629 | 4518 | ||
4630 | void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, | 4519 | static void dsi_display_disable(struct omap_dss_device *dssdev, |
4631 | bool disconnect_lanes, bool enter_ulps) | 4520 | bool disconnect_lanes, bool enter_ulps) |
4632 | { | 4521 | { |
4633 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4522 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -4651,9 +4540,8 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, | |||
4651 | 4540 | ||
4652 | mutex_unlock(&dsi->lock); | 4541 | mutex_unlock(&dsi->lock); |
4653 | } | 4542 | } |
4654 | EXPORT_SYMBOL(omapdss_dsi_display_disable); | ||
4655 | 4543 | ||
4656 | int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) | 4544 | static int dsi_enable_te(struct omap_dss_device *dssdev, bool enable) |
4657 | { | 4545 | { |
4658 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4546 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4659 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4547 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -4661,7 +4549,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) | |||
4661 | dsi->te_enabled = enable; | 4549 | dsi->te_enabled = enable; |
4662 | return 0; | 4550 | return 0; |
4663 | } | 4551 | } |
4664 | EXPORT_SYMBOL(omapdss_dsi_enable_te); | ||
4665 | 4552 | ||
4666 | #ifdef PRINT_VERBOSE_VM_TIMINGS | 4553 | #ifdef PRINT_VERBOSE_VM_TIMINGS |
4667 | static void print_dsi_vm(const char *str, | 4554 | static void print_dsi_vm(const char *str, |
@@ -5136,7 +5023,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi, | |||
5136 | dsi_vm_calc_pll_cb, ctx); | 5023 | dsi_vm_calc_pll_cb, ctx); |
5137 | } | 5024 | } |
5138 | 5025 | ||
5139 | int omapdss_dsi_set_config(struct omap_dss_device *dssdev, | 5026 | static int dsi_set_config(struct omap_dss_device *dssdev, |
5140 | const struct omap_dss_dsi_config *config) | 5027 | const struct omap_dss_dsi_config *config) |
5141 | { | 5028 | { |
5142 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 5029 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -5184,7 +5071,6 @@ err: | |||
5184 | 5071 | ||
5185 | return r; | 5072 | return r; |
5186 | } | 5073 | } |
5187 | EXPORT_SYMBOL(omapdss_dsi_set_config); | ||
5188 | 5074 | ||
5189 | /* | 5075 | /* |
5190 | * Return a hardcoded channel for the DSI output. This should work for | 5076 | * Return a hardcoded channel for the DSI output. This should work for |
@@ -5235,7 +5121,7 @@ static enum omap_channel dsi_get_channel(int module_id) | |||
5235 | } | 5121 | } |
5236 | } | 5122 | } |
5237 | 5123 | ||
5238 | int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) | 5124 | static int dsi_request_vc(struct omap_dss_device *dssdev, int *channel) |
5239 | { | 5125 | { |
5240 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 5126 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
5241 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 5127 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -5252,9 +5138,8 @@ int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) | |||
5252 | DSSERR("cannot get VC for display %s", dssdev->name); | 5138 | DSSERR("cannot get VC for display %s", dssdev->name); |
5253 | return -ENOSPC; | 5139 | return -ENOSPC; |
5254 | } | 5140 | } |
5255 | EXPORT_SYMBOL(omap_dsi_request_vc); | ||
5256 | 5141 | ||
5257 | int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) | 5142 | static int dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) |
5258 | { | 5143 | { |
5259 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 5144 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
5260 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 5145 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -5279,9 +5164,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) | |||
5279 | 5164 | ||
5280 | return 0; | 5165 | return 0; |
5281 | } | 5166 | } |
5282 | EXPORT_SYMBOL(omap_dsi_set_vc_id); | ||
5283 | 5167 | ||
5284 | void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) | 5168 | static void dsi_release_vc(struct omap_dss_device *dssdev, int channel) |
5285 | { | 5169 | { |
5286 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 5170 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
5287 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 5171 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
@@ -5292,7 +5176,6 @@ void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) | |||
5292 | dsi->vc[channel].vc_id = 0; | 5176 | dsi->vc[channel].vc_id = 0; |
5293 | } | 5177 | } |
5294 | } | 5178 | } |
5295 | EXPORT_SYMBOL(omap_dsi_release_vc); | ||
5296 | 5179 | ||
5297 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev) | 5180 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev) |
5298 | { | 5181 | { |
@@ -5348,79 +5231,6 @@ static int dsi_get_clocks(struct platform_device *dsidev) | |||
5348 | return 0; | 5231 | return 0; |
5349 | } | 5232 | } |
5350 | 5233 | ||
5351 | static struct omap_dss_device *dsi_find_dssdev(struct platform_device *pdev) | ||
5352 | { | ||
5353 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
5354 | struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); | ||
5355 | const char *def_disp_name = omapdss_get_default_display_name(); | ||
5356 | struct omap_dss_device *def_dssdev; | ||
5357 | int i; | ||
5358 | |||
5359 | def_dssdev = NULL; | ||
5360 | |||
5361 | for (i = 0; i < pdata->num_devices; ++i) { | ||
5362 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
5363 | |||
5364 | if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) | ||
5365 | continue; | ||
5366 | |||
5367 | if (dssdev->phy.dsi.module != dsi->module_id) | ||
5368 | continue; | ||
5369 | |||
5370 | if (def_dssdev == NULL) | ||
5371 | def_dssdev = dssdev; | ||
5372 | |||
5373 | if (def_disp_name != NULL && | ||
5374 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
5375 | def_dssdev = dssdev; | ||
5376 | break; | ||
5377 | } | ||
5378 | } | ||
5379 | |||
5380 | return def_dssdev; | ||
5381 | } | ||
5382 | |||
5383 | static int dsi_probe_pdata(struct platform_device *dsidev) | ||
5384 | { | ||
5385 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
5386 | struct omap_dss_device *plat_dssdev; | ||
5387 | struct omap_dss_device *dssdev; | ||
5388 | int r; | ||
5389 | |||
5390 | plat_dssdev = dsi_find_dssdev(dsidev); | ||
5391 | |||
5392 | if (!plat_dssdev) | ||
5393 | return 0; | ||
5394 | |||
5395 | r = dsi_regulator_init(dsidev); | ||
5396 | if (r) | ||
5397 | return r; | ||
5398 | |||
5399 | dssdev = dss_alloc_and_init_device(&dsidev->dev); | ||
5400 | if (!dssdev) | ||
5401 | return -ENOMEM; | ||
5402 | |||
5403 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
5404 | |||
5405 | r = omapdss_output_set_device(&dsi->output, dssdev); | ||
5406 | if (r) { | ||
5407 | DSSERR("failed to connect output to new device: %s\n", | ||
5408 | dssdev->name); | ||
5409 | dss_put_device(dssdev); | ||
5410 | return r; | ||
5411 | } | ||
5412 | |||
5413 | r = dss_add_device(dssdev); | ||
5414 | if (r) { | ||
5415 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
5416 | omapdss_output_unset_device(&dsi->output); | ||
5417 | dss_put_device(dssdev); | ||
5418 | return r; | ||
5419 | } | ||
5420 | |||
5421 | return 0; | ||
5422 | } | ||
5423 | |||
5424 | static int dsi_connect(struct omap_dss_device *dssdev, | 5234 | static int dsi_connect(struct omap_dss_device *dssdev, |
5425 | struct omap_dss_device *dst) | 5235 | struct omap_dss_device *dst) |
5426 | { | 5236 | { |
@@ -5454,9 +5264,9 @@ static int dsi_connect(struct omap_dss_device *dssdev, | |||
5454 | static void dsi_disconnect(struct omap_dss_device *dssdev, | 5264 | static void dsi_disconnect(struct omap_dss_device *dssdev, |
5455 | struct omap_dss_device *dst) | 5265 | struct omap_dss_device *dst) |
5456 | { | 5266 | { |
5457 | WARN_ON(dst != dssdev->device); | 5267 | WARN_ON(dst != dssdev->dst); |
5458 | 5268 | ||
5459 | if (dst != dssdev->device) | 5269 | if (dst != dssdev->dst) |
5460 | return; | 5270 | return; |
5461 | 5271 | ||
5462 | omapdss_output_unset_device(dssdev); | 5272 | omapdss_output_unset_device(dssdev); |
@@ -5472,24 +5282,24 @@ static const struct omapdss_dsi_ops dsi_ops = { | |||
5472 | .bus_lock = dsi_bus_lock, | 5282 | .bus_lock = dsi_bus_lock, |
5473 | .bus_unlock = dsi_bus_unlock, | 5283 | .bus_unlock = dsi_bus_unlock, |
5474 | 5284 | ||
5475 | .enable = omapdss_dsi_display_enable, | 5285 | .enable = dsi_display_enable, |
5476 | .disable = omapdss_dsi_display_disable, | 5286 | .disable = dsi_display_disable, |
5477 | 5287 | ||
5478 | .enable_hs = omapdss_dsi_vc_enable_hs, | 5288 | .enable_hs = dsi_vc_enable_hs, |
5479 | 5289 | ||
5480 | .configure_pins = omapdss_dsi_configure_pins, | 5290 | .configure_pins = dsi_configure_pins, |
5481 | .set_config = omapdss_dsi_set_config, | 5291 | .set_config = dsi_set_config, |
5482 | 5292 | ||
5483 | .enable_video_output = dsi_enable_video_output, | 5293 | .enable_video_output = dsi_enable_video_output, |
5484 | .disable_video_output = dsi_disable_video_output, | 5294 | .disable_video_output = dsi_disable_video_output, |
5485 | 5295 | ||
5486 | .update = omap_dsi_update, | 5296 | .update = dsi_update, |
5487 | 5297 | ||
5488 | .enable_te = omapdss_dsi_enable_te, | 5298 | .enable_te = dsi_enable_te, |
5489 | 5299 | ||
5490 | .request_vc = omap_dsi_request_vc, | 5300 | .request_vc = dsi_request_vc, |
5491 | .set_vc_id = omap_dsi_set_vc_id, | 5301 | .set_vc_id = dsi_set_vc_id, |
5492 | .release_vc = omap_dsi_release_vc, | 5302 | .release_vc = dsi_release_vc, |
5493 | 5303 | ||
5494 | .dcs_write = dsi_vc_dcs_write, | 5304 | .dcs_write = dsi_vc_dcs_write, |
5495 | .dcs_write_nosync = dsi_vc_dcs_write_nosync, | 5305 | .dcs_write_nosync = dsi_vc_dcs_write_nosync, |
@@ -5627,12 +5437,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev) | |||
5627 | 5437 | ||
5628 | dsi_init_output(dsidev); | 5438 | dsi_init_output(dsidev); |
5629 | 5439 | ||
5630 | if (dsidev->dev.platform_data) { | ||
5631 | r = dsi_probe_pdata(dsidev); | ||
5632 | if (r) | ||
5633 | goto err_probe; | ||
5634 | } | ||
5635 | |||
5636 | dsi_runtime_put(dsidev); | 5440 | dsi_runtime_put(dsidev); |
5637 | 5441 | ||
5638 | if (dsi->module_id == 0) | 5442 | if (dsi->module_id == 0) |
@@ -5648,9 +5452,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev) | |||
5648 | #endif | 5452 | #endif |
5649 | return 0; | 5453 | return 0; |
5650 | 5454 | ||
5651 | err_probe: | ||
5652 | dsi_runtime_put(dsidev); | ||
5653 | dsi_uninit_output(dsidev); | ||
5654 | err_runtime_get: | 5455 | err_runtime_get: |
5655 | pm_runtime_disable(&dsidev->dev); | 5456 | pm_runtime_disable(&dsidev->dev); |
5656 | return r; | 5457 | return r; |
@@ -5662,8 +5463,6 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) | |||
5662 | 5463 | ||
5663 | WARN_ON(dsi->scp_clk_refcount > 0); | 5464 | WARN_ON(dsi->scp_clk_refcount > 0); |
5664 | 5465 | ||
5665 | dss_unregister_child_devices(&dsidev->dev); | ||
5666 | |||
5667 | dsi_uninit_output(dsidev); | 5466 | dsi_uninit_output(dsidev); |
5668 | 5467 | ||
5669 | pm_runtime_disable(&dsidev->dev); | 5468 | pm_runtime_disable(&dsidev->dev); |
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 50a2362ef8f8..e172531d196b 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -163,22 +163,11 @@ struct platform_device; | |||
163 | 163 | ||
164 | /* core */ | 164 | /* core */ |
165 | struct platform_device *dss_get_core_pdev(void); | 165 | struct platform_device *dss_get_core_pdev(void); |
166 | struct bus_type *dss_get_bus(void); | ||
167 | struct regulator *dss_get_vdds_dsi(void); | ||
168 | struct regulator *dss_get_vdds_sdi(void); | ||
169 | int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); | 166 | int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); |
170 | void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); | 167 | void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); |
171 | int dss_set_min_bus_tput(struct device *dev, unsigned long tput); | 168 | int dss_set_min_bus_tput(struct device *dev, unsigned long tput); |
172 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); | 169 | int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); |
173 | 170 | ||
174 | struct omap_dss_device *dss_alloc_and_init_device(struct device *parent); | ||
175 | int dss_add_device(struct omap_dss_device *dssdev); | ||
176 | void dss_unregister_device(struct omap_dss_device *dssdev); | ||
177 | void dss_unregister_child_devices(struct device *parent); | ||
178 | void dss_put_device(struct omap_dss_device *dssdev); | ||
179 | void dss_copy_device_pdata(struct omap_dss_device *dst, | ||
180 | const struct omap_dss_device *src); | ||
181 | |||
182 | /* display */ | 171 | /* display */ |
183 | int dss_suspend_all_devices(void); | 172 | int dss_suspend_all_devices(void); |
184 | int dss_resume_all_devices(void); | 173 | int dss_resume_all_devices(void); |
@@ -436,44 +425,10 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi, | |||
436 | /* VENC */ | 425 | /* VENC */ |
437 | int venc_init_platform_driver(void) __init; | 426 | int venc_init_platform_driver(void) __init; |
438 | void venc_uninit_platform_driver(void) __exit; | 427 | void venc_uninit_platform_driver(void) __exit; |
439 | int omapdss_venc_display_enable(struct omap_dss_device *dssdev); | ||
440 | void omapdss_venc_display_disable(struct omap_dss_device *dssdev); | ||
441 | void omapdss_venc_set_timings(struct omap_dss_device *dssdev, | ||
442 | struct omap_video_timings *timings); | ||
443 | int omapdss_venc_check_timings(struct omap_dss_device *dssdev, | ||
444 | struct omap_video_timings *timings); | ||
445 | u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev); | ||
446 | int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss); | ||
447 | void omapdss_venc_set_type(struct omap_dss_device *dssdev, | ||
448 | enum omap_dss_venc_type type); | ||
449 | void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, | ||
450 | bool invert_polarity); | ||
451 | int venc_panel_init(void); | ||
452 | void venc_panel_exit(void); | ||
453 | 428 | ||
454 | /* HDMI */ | 429 | /* HDMI */ |
455 | int hdmi_init_platform_driver(void) __init; | 430 | int hdmi_init_platform_driver(void) __init; |
456 | void hdmi_uninit_platform_driver(void) __exit; | 431 | void hdmi_uninit_platform_driver(void) __exit; |
457 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); | ||
458 | void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); | ||
459 | int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev); | ||
460 | void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev); | ||
461 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, | ||
462 | struct omap_video_timings *timings); | ||
463 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | ||
464 | struct omap_video_timings *timings); | ||
465 | int omapdss_hdmi_read_edid(u8 *buf, int len); | ||
466 | bool omapdss_hdmi_detect(void); | ||
467 | int hdmi_panel_init(void); | ||
468 | void hdmi_panel_exit(void); | ||
469 | #ifdef CONFIG_OMAP4_DSS_HDMI_AUDIO | ||
470 | int hdmi_audio_enable(void); | ||
471 | void hdmi_audio_disable(void); | ||
472 | int hdmi_audio_start(void); | ||
473 | void hdmi_audio_stop(void); | ||
474 | bool hdmi_mode_has_audio(void); | ||
475 | int hdmi_audio_config(struct omap_dss_audio *audio); | ||
476 | #endif | ||
477 | 432 | ||
478 | /* RFBI */ | 433 | /* RFBI */ |
479 | int rfbi_init_platform_driver(void) __init; | 434 | int rfbi_init_platform_driver(void) __init; |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 44a885b92825..82a964074993 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -66,10 +66,6 @@ static struct { | |||
66 | struct clk *sys_clk; | 66 | struct clk *sys_clk; |
67 | struct regulator *vdda_hdmi_dac_reg; | 67 | struct regulator *vdda_hdmi_dac_reg; |
68 | 68 | ||
69 | int ct_cp_hpd_gpio; | ||
70 | int ls_oe_gpio; | ||
71 | int hpd_gpio; | ||
72 | |||
73 | bool core_enabled; | 69 | bool core_enabled; |
74 | 70 | ||
75 | struct omap_dss_device output; | 71 | struct omap_dss_device output; |
@@ -353,40 +349,6 @@ static int hdmi_init_regulator(void) | |||
353 | return 0; | 349 | return 0; |
354 | } | 350 | } |
355 | 351 | ||
356 | static int hdmi_init_display(struct omap_dss_device *dssdev) | ||
357 | { | ||
358 | int r; | ||
359 | |||
360 | struct gpio gpios[] = { | ||
361 | { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" }, | ||
362 | { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" }, | ||
363 | { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" }, | ||
364 | }; | ||
365 | |||
366 | DSSDBG("init_display\n"); | ||
367 | |||
368 | dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); | ||
369 | |||
370 | r = hdmi_init_regulator(); | ||
371 | if (r) | ||
372 | return r; | ||
373 | |||
374 | r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); | ||
375 | if (r) | ||
376 | return r; | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static void hdmi_uninit_display(struct omap_dss_device *dssdev) | ||
382 | { | ||
383 | DSSDBG("uninit_display\n"); | ||
384 | |||
385 | gpio_free(hdmi.ct_cp_hpd_gpio); | ||
386 | gpio_free(hdmi.ls_oe_gpio); | ||
387 | gpio_free(hdmi.hpd_gpio); | ||
388 | } | ||
389 | |||
390 | static const struct hdmi_config *hdmi_find_timing( | 352 | static const struct hdmi_config *hdmi_find_timing( |
391 | const struct hdmi_config *timings_arr, | 353 | const struct hdmi_config *timings_arr, |
392 | int len) | 354 | int len) |
@@ -517,17 +479,9 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) | |||
517 | { | 479 | { |
518 | int r; | 480 | int r; |
519 | 481 | ||
520 | if (gpio_is_valid(hdmi.ct_cp_hpd_gpio)) | ||
521 | gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); | ||
522 | if (gpio_is_valid(hdmi.ls_oe_gpio)) | ||
523 | gpio_set_value(hdmi.ls_oe_gpio, 1); | ||
524 | |||
525 | /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */ | ||
526 | udelay(300); | ||
527 | |||
528 | r = regulator_enable(hdmi.vdda_hdmi_dac_reg); | 482 | r = regulator_enable(hdmi.vdda_hdmi_dac_reg); |
529 | if (r) | 483 | if (r) |
530 | goto err_vdac_enable; | 484 | return r; |
531 | 485 | ||
532 | r = hdmi_runtime_get(); | 486 | r = hdmi_runtime_get(); |
533 | if (r) | 487 | if (r) |
@@ -542,11 +496,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) | |||
542 | 496 | ||
543 | err_runtime_get: | 497 | err_runtime_get: |
544 | regulator_disable(hdmi.vdda_hdmi_dac_reg); | 498 | regulator_disable(hdmi.vdda_hdmi_dac_reg); |
545 | err_vdac_enable: | 499 | |
546 | if (gpio_is_valid(hdmi.ct_cp_hpd_gpio)) | ||
547 | gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); | ||
548 | if (gpio_is_valid(hdmi.ls_oe_gpio)) | ||
549 | gpio_set_value(hdmi.ls_oe_gpio, 0); | ||
550 | return r; | 500 | return r; |
551 | } | 501 | } |
552 | 502 | ||
@@ -556,10 +506,6 @@ static void hdmi_power_off_core(struct omap_dss_device *dssdev) | |||
556 | 506 | ||
557 | hdmi_runtime_put(); | 507 | hdmi_runtime_put(); |
558 | regulator_disable(hdmi.vdda_hdmi_dac_reg); | 508 | regulator_disable(hdmi.vdda_hdmi_dac_reg); |
559 | if (gpio_is_valid(hdmi.ct_cp_hpd_gpio)) | ||
560 | gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); | ||
561 | if (gpio_is_valid(hdmi.ls_oe_gpio)) | ||
562 | gpio_set_value(hdmi.ls_oe_gpio, 0); | ||
563 | } | 509 | } |
564 | 510 | ||
565 | static int hdmi_power_on_full(struct omap_dss_device *dssdev) | 511 | static int hdmi_power_on_full(struct omap_dss_device *dssdev) |
@@ -640,7 +586,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev) | |||
640 | hdmi_power_off_core(dssdev); | 586 | hdmi_power_off_core(dssdev); |
641 | } | 587 | } |
642 | 588 | ||
643 | int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | 589 | static int hdmi_display_check_timing(struct omap_dss_device *dssdev, |
644 | struct omap_video_timings *timings) | 590 | struct omap_video_timings *timings) |
645 | { | 591 | { |
646 | struct hdmi_cm cm; | 592 | struct hdmi_cm cm; |
@@ -654,7 +600,7 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, | |||
654 | 600 | ||
655 | } | 601 | } |
656 | 602 | ||
657 | void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, | 603 | static void hdmi_display_set_timing(struct omap_dss_device *dssdev, |
658 | struct omap_video_timings *timings) | 604 | struct omap_video_timings *timings) |
659 | { | 605 | { |
660 | struct hdmi_cm cm; | 606 | struct hdmi_cm cm; |
@@ -666,15 +612,16 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, | |||
666 | hdmi.ip_data.cfg.cm = cm; | 612 | hdmi.ip_data.cfg.cm = cm; |
667 | 613 | ||
668 | t = hdmi_get_timings(); | 614 | t = hdmi_get_timings(); |
669 | if (t != NULL) | 615 | if (t != NULL) { |
670 | hdmi.ip_data.cfg = *t; | 616 | hdmi.ip_data.cfg = *t; |
671 | 617 | ||
672 | dispc_set_tv_pclk(t->timings.pixel_clock * 1000); | 618 | dispc_set_tv_pclk(t->timings.pixel_clock * 1000); |
619 | } | ||
673 | 620 | ||
674 | mutex_unlock(&hdmi.lock); | 621 | mutex_unlock(&hdmi.lock); |
675 | } | 622 | } |
676 | 623 | ||
677 | static void omapdss_hdmi_display_get_timings(struct omap_dss_device *dssdev, | 624 | static void hdmi_display_get_timings(struct omap_dss_device *dssdev, |
678 | struct omap_video_timings *timings) | 625 | struct omap_video_timings *timings) |
679 | { | 626 | { |
680 | const struct hdmi_config *cfg; | 627 | const struct hdmi_config *cfg; |
@@ -704,7 +651,7 @@ static void hdmi_dump_regs(struct seq_file *s) | |||
704 | mutex_unlock(&hdmi.lock); | 651 | mutex_unlock(&hdmi.lock); |
705 | } | 652 | } |
706 | 653 | ||
707 | int omapdss_hdmi_read_edid(u8 *buf, int len) | 654 | static int read_edid(u8 *buf, int len) |
708 | { | 655 | { |
709 | int r; | 656 | int r; |
710 | 657 | ||
@@ -721,24 +668,7 @@ int omapdss_hdmi_read_edid(u8 *buf, int len) | |||
721 | return r; | 668 | return r; |
722 | } | 669 | } |
723 | 670 | ||
724 | bool omapdss_hdmi_detect(void) | 671 | static int hdmi_display_enable(struct omap_dss_device *dssdev) |
725 | { | ||
726 | int r; | ||
727 | |||
728 | mutex_lock(&hdmi.lock); | ||
729 | |||
730 | r = hdmi_runtime_get(); | ||
731 | BUG_ON(r); | ||
732 | |||
733 | r = gpio_get_value(hdmi.hpd_gpio); | ||
734 | |||
735 | hdmi_runtime_put(); | ||
736 | mutex_unlock(&hdmi.lock); | ||
737 | |||
738 | return r == 1; | ||
739 | } | ||
740 | |||
741 | int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) | ||
742 | { | 672 | { |
743 | struct omap_dss_device *out = &hdmi.output; | 673 | struct omap_dss_device *out = &hdmi.output; |
744 | int r = 0; | 674 | int r = 0; |
@@ -767,7 +697,7 @@ err0: | |||
767 | return r; | 697 | return r; |
768 | } | 698 | } |
769 | 699 | ||
770 | void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) | 700 | static void hdmi_display_disable(struct omap_dss_device *dssdev) |
771 | { | 701 | { |
772 | DSSDBG("Enter hdmi_display_disable\n"); | 702 | DSSDBG("Enter hdmi_display_disable\n"); |
773 | 703 | ||
@@ -778,7 +708,7 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) | |||
778 | mutex_unlock(&hdmi.lock); | 708 | mutex_unlock(&hdmi.lock); |
779 | } | 709 | } |
780 | 710 | ||
781 | int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev) | 711 | static int hdmi_core_enable(struct omap_dss_device *dssdev) |
782 | { | 712 | { |
783 | int r = 0; | 713 | int r = 0; |
784 | 714 | ||
@@ -800,7 +730,7 @@ err0: | |||
800 | return r; | 730 | return r; |
801 | } | 731 | } |
802 | 732 | ||
803 | void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev) | 733 | static void hdmi_core_disable(struct omap_dss_device *dssdev) |
804 | { | 734 | { |
805 | DSSDBG("Enter omapdss_hdmi_core_disable\n"); | 735 | DSSDBG("Enter omapdss_hdmi_core_disable\n"); |
806 | 736 | ||
@@ -927,35 +857,7 @@ int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) | |||
927 | return 0; | 857 | return 0; |
928 | } | 858 | } |
929 | 859 | ||
930 | int hdmi_audio_enable(void) | 860 | static bool hdmi_mode_has_audio(void) |
931 | { | ||
932 | DSSDBG("audio_enable\n"); | ||
933 | |||
934 | return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); | ||
935 | } | ||
936 | |||
937 | void hdmi_audio_disable(void) | ||
938 | { | ||
939 | DSSDBG("audio_disable\n"); | ||
940 | |||
941 | hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); | ||
942 | } | ||
943 | |||
944 | int hdmi_audio_start(void) | ||
945 | { | ||
946 | DSSDBG("audio_start\n"); | ||
947 | |||
948 | return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); | ||
949 | } | ||
950 | |||
951 | void hdmi_audio_stop(void) | ||
952 | { | ||
953 | DSSDBG("audio_stop\n"); | ||
954 | |||
955 | hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); | ||
956 | } | ||
957 | |||
958 | bool hdmi_mode_has_audio(void) | ||
959 | { | 861 | { |
960 | if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) | 862 | if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) |
961 | return true; | 863 | return true; |
@@ -963,92 +865,8 @@ bool hdmi_mode_has_audio(void) | |||
963 | return false; | 865 | return false; |
964 | } | 866 | } |
965 | 867 | ||
966 | int hdmi_audio_config(struct omap_dss_audio *audio) | ||
967 | { | ||
968 | return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); | ||
969 | } | ||
970 | |||
971 | #endif | 868 | #endif |
972 | 869 | ||
973 | static struct omap_dss_device *hdmi_find_dssdev(struct platform_device *pdev) | ||
974 | { | ||
975 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
976 | const char *def_disp_name = omapdss_get_default_display_name(); | ||
977 | struct omap_dss_device *def_dssdev; | ||
978 | int i; | ||
979 | |||
980 | def_dssdev = NULL; | ||
981 | |||
982 | for (i = 0; i < pdata->num_devices; ++i) { | ||
983 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
984 | |||
985 | if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) | ||
986 | continue; | ||
987 | |||
988 | if (def_dssdev == NULL) | ||
989 | def_dssdev = dssdev; | ||
990 | |||
991 | if (def_disp_name != NULL && | ||
992 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
993 | def_dssdev = dssdev; | ||
994 | break; | ||
995 | } | ||
996 | } | ||
997 | |||
998 | return def_dssdev; | ||
999 | } | ||
1000 | |||
1001 | static int hdmi_probe_pdata(struct platform_device *pdev) | ||
1002 | { | ||
1003 | struct omap_dss_device *plat_dssdev; | ||
1004 | struct omap_dss_device *dssdev; | ||
1005 | struct omap_dss_hdmi_data *priv; | ||
1006 | int r; | ||
1007 | |||
1008 | plat_dssdev = hdmi_find_dssdev(pdev); | ||
1009 | |||
1010 | if (!plat_dssdev) | ||
1011 | return 0; | ||
1012 | |||
1013 | dssdev = dss_alloc_and_init_device(&pdev->dev); | ||
1014 | if (!dssdev) | ||
1015 | return -ENOMEM; | ||
1016 | |||
1017 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
1018 | |||
1019 | priv = dssdev->data; | ||
1020 | |||
1021 | hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio; | ||
1022 | hdmi.ls_oe_gpio = priv->ls_oe_gpio; | ||
1023 | hdmi.hpd_gpio = priv->hpd_gpio; | ||
1024 | |||
1025 | r = hdmi_init_display(dssdev); | ||
1026 | if (r) { | ||
1027 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
1028 | dss_put_device(dssdev); | ||
1029 | return r; | ||
1030 | } | ||
1031 | |||
1032 | r = omapdss_output_set_device(&hdmi.output, dssdev); | ||
1033 | if (r) { | ||
1034 | DSSERR("failed to connect output to new device: %s\n", | ||
1035 | dssdev->name); | ||
1036 | dss_put_device(dssdev); | ||
1037 | return r; | ||
1038 | } | ||
1039 | |||
1040 | r = dss_add_device(dssdev); | ||
1041 | if (r) { | ||
1042 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
1043 | omapdss_output_unset_device(&hdmi.output); | ||
1044 | hdmi_uninit_display(dssdev); | ||
1045 | dss_put_device(dssdev); | ||
1046 | return r; | ||
1047 | } | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | static int hdmi_connect(struct omap_dss_device *dssdev, | 870 | static int hdmi_connect(struct omap_dss_device *dssdev, |
1053 | struct omap_dss_device *dst) | 871 | struct omap_dss_device *dst) |
1054 | { | 872 | { |
@@ -1083,9 +901,9 @@ static int hdmi_connect(struct omap_dss_device *dssdev, | |||
1083 | static void hdmi_disconnect(struct omap_dss_device *dssdev, | 901 | static void hdmi_disconnect(struct omap_dss_device *dssdev, |
1084 | struct omap_dss_device *dst) | 902 | struct omap_dss_device *dst) |
1085 | { | 903 | { |
1086 | WARN_ON(dst != dssdev->device); | 904 | WARN_ON(dst != dssdev->dst); |
1087 | 905 | ||
1088 | if (dst != dssdev->device) | 906 | if (dst != dssdev->dst) |
1089 | return; | 907 | return; |
1090 | 908 | ||
1091 | omapdss_output_unset_device(dssdev); | 909 | omapdss_output_unset_device(dssdev); |
@@ -1103,21 +921,21 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, | |||
1103 | need_enable = hdmi.core_enabled == false; | 921 | need_enable = hdmi.core_enabled == false; |
1104 | 922 | ||
1105 | if (need_enable) { | 923 | if (need_enable) { |
1106 | r = omapdss_hdmi_core_enable(dssdev); | 924 | r = hdmi_core_enable(dssdev); |
1107 | if (r) | 925 | if (r) |
1108 | return r; | 926 | return r; |
1109 | } | 927 | } |
1110 | 928 | ||
1111 | r = omapdss_hdmi_read_edid(edid, len); | 929 | r = read_edid(edid, len); |
1112 | 930 | ||
1113 | if (need_enable) | 931 | if (need_enable) |
1114 | omapdss_hdmi_core_disable(dssdev); | 932 | hdmi_core_disable(dssdev); |
1115 | 933 | ||
1116 | return r; | 934 | return r; |
1117 | } | 935 | } |
1118 | 936 | ||
1119 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 937 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
1120 | static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) | 938 | static int hdmi_audio_enable(struct omap_dss_device *dssdev) |
1121 | { | 939 | { |
1122 | int r; | 940 | int r; |
1123 | 941 | ||
@@ -1128,7 +946,8 @@ static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) | |||
1128 | goto err; | 946 | goto err; |
1129 | } | 947 | } |
1130 | 948 | ||
1131 | r = hdmi_audio_enable(); | 949 | |
950 | r = hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); | ||
1132 | if (r) | 951 | if (r) |
1133 | goto err; | 952 | goto err; |
1134 | 953 | ||
@@ -1140,22 +959,22 @@ err: | |||
1140 | return r; | 959 | return r; |
1141 | } | 960 | } |
1142 | 961 | ||
1143 | static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev) | 962 | static void hdmi_audio_disable(struct omap_dss_device *dssdev) |
1144 | { | 963 | { |
1145 | hdmi_audio_disable(); | 964 | hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); |
1146 | } | 965 | } |
1147 | 966 | ||
1148 | static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev) | 967 | static int hdmi_audio_start(struct omap_dss_device *dssdev) |
1149 | { | 968 | { |
1150 | return hdmi_audio_start(); | 969 | return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); |
1151 | } | 970 | } |
1152 | 971 | ||
1153 | static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev) | 972 | static void hdmi_audio_stop(struct omap_dss_device *dssdev) |
1154 | { | 973 | { |
1155 | hdmi_audio_stop(); | 974 | hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); |
1156 | } | 975 | } |
1157 | 976 | ||
1158 | static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) | 977 | static bool hdmi_audio_supported(struct omap_dss_device *dssdev) |
1159 | { | 978 | { |
1160 | bool r; | 979 | bool r; |
1161 | 980 | ||
@@ -1167,7 +986,7 @@ static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) | |||
1167 | return r; | 986 | return r; |
1168 | } | 987 | } |
1169 | 988 | ||
1170 | static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, | 989 | static int hdmi_audio_config(struct omap_dss_device *dssdev, |
1171 | struct omap_dss_audio *audio) | 990 | struct omap_dss_audio *audio) |
1172 | { | 991 | { |
1173 | int r; | 992 | int r; |
@@ -1179,7 +998,7 @@ static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, | |||
1179 | goto err; | 998 | goto err; |
1180 | } | 999 | } |
1181 | 1000 | ||
1182 | r = hdmi_audio_config(audio); | 1001 | r = hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); |
1183 | if (r) | 1002 | if (r) |
1184 | goto err; | 1003 | goto err; |
1185 | 1004 | ||
@@ -1191,30 +1010,30 @@ err: | |||
1191 | return r; | 1010 | return r; |
1192 | } | 1011 | } |
1193 | #else | 1012 | #else |
1194 | static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) | 1013 | static int hdmi_audio_enable(struct omap_dss_device *dssdev) |
1195 | { | 1014 | { |
1196 | return -EPERM; | 1015 | return -EPERM; |
1197 | } | 1016 | } |
1198 | 1017 | ||
1199 | static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev) | 1018 | static void hdmi_audio_disable(struct omap_dss_device *dssdev) |
1200 | { | 1019 | { |
1201 | } | 1020 | } |
1202 | 1021 | ||
1203 | static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev) | 1022 | static int hdmi_audio_start(struct omap_dss_device *dssdev) |
1204 | { | 1023 | { |
1205 | return -EPERM; | 1024 | return -EPERM; |
1206 | } | 1025 | } |
1207 | 1026 | ||
1208 | static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev) | 1027 | static void hdmi_audio_stop(struct omap_dss_device *dssdev) |
1209 | { | 1028 | { |
1210 | } | 1029 | } |
1211 | 1030 | ||
1212 | static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) | 1031 | static bool hdmi_audio_supported(struct omap_dss_device *dssdev) |
1213 | { | 1032 | { |
1214 | return false; | 1033 | return false; |
1215 | } | 1034 | } |
1216 | 1035 | ||
1217 | static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, | 1036 | static int hdmi_audio_config(struct omap_dss_device *dssdev, |
1218 | struct omap_dss_audio *audio) | 1037 | struct omap_dss_audio *audio) |
1219 | { | 1038 | { |
1220 | return -EPERM; | 1039 | return -EPERM; |
@@ -1225,21 +1044,21 @@ static const struct omapdss_hdmi_ops hdmi_ops = { | |||
1225 | .connect = hdmi_connect, | 1044 | .connect = hdmi_connect, |
1226 | .disconnect = hdmi_disconnect, | 1045 | .disconnect = hdmi_disconnect, |
1227 | 1046 | ||
1228 | .enable = omapdss_hdmi_display_enable, | 1047 | .enable = hdmi_display_enable, |
1229 | .disable = omapdss_hdmi_display_disable, | 1048 | .disable = hdmi_display_disable, |
1230 | 1049 | ||
1231 | .check_timings = omapdss_hdmi_display_check_timing, | 1050 | .check_timings = hdmi_display_check_timing, |
1232 | .set_timings = omapdss_hdmi_display_set_timing, | 1051 | .set_timings = hdmi_display_set_timing, |
1233 | .get_timings = omapdss_hdmi_display_get_timings, | 1052 | .get_timings = hdmi_display_get_timings, |
1234 | 1053 | ||
1235 | .read_edid = hdmi_read_edid, | 1054 | .read_edid = hdmi_read_edid, |
1236 | 1055 | ||
1237 | .audio_enable = omapdss_hdmi_audio_enable, | 1056 | .audio_enable = hdmi_audio_enable, |
1238 | .audio_disable = omapdss_hdmi_audio_disable, | 1057 | .audio_disable = hdmi_audio_disable, |
1239 | .audio_start = omapdss_hdmi_audio_start, | 1058 | .audio_start = hdmi_audio_start, |
1240 | .audio_stop = omapdss_hdmi_audio_stop, | 1059 | .audio_stop = hdmi_audio_stop, |
1241 | .audio_supported = omapdss_hdmi_audio_supported, | 1060 | .audio_supported = hdmi_audio_supported, |
1242 | .audio_config = omapdss_hdmi_audio_config, | 1061 | .audio_config = hdmi_audio_config, |
1243 | }; | 1062 | }; |
1244 | 1063 | ||
1245 | static void hdmi_init_output(struct platform_device *pdev) | 1064 | static void hdmi_init_output(struct platform_device *pdev) |
@@ -1301,50 +1120,15 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
1301 | hdmi.ip_data.pll_offset = HDMI_PLLCTRL; | 1120 | hdmi.ip_data.pll_offset = HDMI_PLLCTRL; |
1302 | hdmi.ip_data.phy_offset = HDMI_PHY; | 1121 | hdmi.ip_data.phy_offset = HDMI_PHY; |
1303 | 1122 | ||
1304 | hdmi.ct_cp_hpd_gpio = -1; | ||
1305 | hdmi.ls_oe_gpio = -1; | ||
1306 | hdmi.hpd_gpio = -1; | ||
1307 | |||
1308 | hdmi_init_output(pdev); | 1123 | hdmi_init_output(pdev); |
1309 | 1124 | ||
1310 | r = hdmi_panel_init(); | ||
1311 | if (r) { | ||
1312 | DSSERR("can't init panel\n"); | ||
1313 | return r; | ||
1314 | } | ||
1315 | |||
1316 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); | 1125 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); |
1317 | 1126 | ||
1318 | if (pdev->dev.platform_data) { | ||
1319 | r = hdmi_probe_pdata(pdev); | ||
1320 | if (r) | ||
1321 | goto err_probe; | ||
1322 | } | ||
1323 | |||
1324 | return 0; | ||
1325 | |||
1326 | err_probe: | ||
1327 | hdmi_panel_exit(); | ||
1328 | hdmi_uninit_output(pdev); | ||
1329 | pm_runtime_disable(&pdev->dev); | ||
1330 | return r; | ||
1331 | } | ||
1332 | |||
1333 | static int __exit hdmi_remove_child(struct device *dev, void *data) | ||
1334 | { | ||
1335 | struct omap_dss_device *dssdev = to_dss_device(dev); | ||
1336 | hdmi_uninit_display(dssdev); | ||
1337 | return 0; | 1127 | return 0; |
1338 | } | 1128 | } |
1339 | 1129 | ||
1340 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | 1130 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) |
1341 | { | 1131 | { |
1342 | device_for_each_child(&pdev->dev, NULL, hdmi_remove_child); | ||
1343 | |||
1344 | dss_unregister_child_devices(&pdev->dev); | ||
1345 | |||
1346 | hdmi_panel_exit(); | ||
1347 | |||
1348 | hdmi_uninit_output(pdev); | 1132 | hdmi_uninit_output(pdev); |
1349 | 1133 | ||
1350 | pm_runtime_disable(&pdev->dev); | 1134 | pm_runtime_disable(&pdev->dev); |
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c deleted file mode 100644 index dfb8eda81b61..000000000000 --- a/drivers/video/omap2/dss/hdmi_panel.c +++ /dev/null | |||
@@ -1,414 +0,0 @@ | |||
1 | /* | ||
2 | * hdmi_panel.c | ||
3 | * | ||
4 | * HDMI library support functions for TI OMAP4 processors. | ||
5 | * | ||
6 | * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
7 | * Authors: Mythri P k <mythripk@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License version 2 as published by | ||
11 | * the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <video/omapdss.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #include "dss.h" | ||
31 | |||
32 | static struct { | ||
33 | /* This protects the panel ops, mainly when accessing the HDMI IP. */ | ||
34 | struct mutex lock; | ||
35 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
36 | /* This protects the audio ops, specifically. */ | ||
37 | spinlock_t audio_lock; | ||
38 | #endif | ||
39 | } hdmi; | ||
40 | |||
41 | |||
42 | static int hdmi_panel_probe(struct omap_dss_device *dssdev) | ||
43 | { | ||
44 | /* Initialize default timings to VGA in DVI mode */ | ||
45 | const struct omap_video_timings default_timings = { | ||
46 | .x_res = 640, | ||
47 | .y_res = 480, | ||
48 | .pixel_clock = 25175, | ||
49 | .hsw = 96, | ||
50 | .hfp = 16, | ||
51 | .hbp = 48, | ||
52 | .vsw = 2, | ||
53 | .vfp = 11, | ||
54 | .vbp = 31, | ||
55 | |||
56 | .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
57 | .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, | ||
58 | |||
59 | .interlace = false, | ||
60 | }; | ||
61 | |||
62 | DSSDBG("ENTER hdmi_panel_probe\n"); | ||
63 | |||
64 | dssdev->panel.timings = default_timings; | ||
65 | |||
66 | DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", | ||
67 | dssdev->panel.timings.x_res, | ||
68 | dssdev->panel.timings.y_res); | ||
69 | |||
70 | omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings); | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static void hdmi_panel_remove(struct omap_dss_device *dssdev) | ||
76 | { | ||
77 | |||
78 | } | ||
79 | |||
80 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
81 | static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) | ||
82 | { | ||
83 | unsigned long flags; | ||
84 | int r; | ||
85 | |||
86 | mutex_lock(&hdmi.lock); | ||
87 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
88 | |||
89 | /* enable audio only if the display is active and supports audio */ | ||
90 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || | ||
91 | !hdmi_mode_has_audio()) { | ||
92 | DSSERR("audio not supported or display is off\n"); | ||
93 | r = -EPERM; | ||
94 | goto err; | ||
95 | } | ||
96 | |||
97 | r = hdmi_audio_enable(); | ||
98 | |||
99 | if (!r) | ||
100 | dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; | ||
101 | |||
102 | err: | ||
103 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
104 | mutex_unlock(&hdmi.lock); | ||
105 | return r; | ||
106 | } | ||
107 | |||
108 | static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) | ||
109 | { | ||
110 | unsigned long flags; | ||
111 | |||
112 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
113 | |||
114 | hdmi_audio_disable(); | ||
115 | |||
116 | dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED; | ||
117 | |||
118 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
119 | } | ||
120 | |||
121 | static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) | ||
122 | { | ||
123 | unsigned long flags; | ||
124 | int r; | ||
125 | |||
126 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
127 | /* | ||
128 | * No need to check the panel state. It was checked when trasitioning | ||
129 | * to AUDIO_ENABLED. | ||
130 | */ | ||
131 | if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED) { | ||
132 | DSSERR("audio start from invalid state\n"); | ||
133 | r = -EPERM; | ||
134 | goto err; | ||
135 | } | ||
136 | |||
137 | r = hdmi_audio_start(); | ||
138 | |||
139 | if (!r) | ||
140 | dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING; | ||
141 | |||
142 | err: | ||
143 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
144 | return r; | ||
145 | } | ||
146 | |||
147 | static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) | ||
148 | { | ||
149 | unsigned long flags; | ||
150 | |||
151 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
152 | |||
153 | hdmi_audio_stop(); | ||
154 | dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; | ||
155 | |||
156 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
157 | } | ||
158 | |||
159 | static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) | ||
160 | { | ||
161 | bool r = false; | ||
162 | |||
163 | mutex_lock(&hdmi.lock); | ||
164 | |||
165 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | ||
166 | goto err; | ||
167 | |||
168 | if (!hdmi_mode_has_audio()) | ||
169 | goto err; | ||
170 | |||
171 | r = true; | ||
172 | err: | ||
173 | mutex_unlock(&hdmi.lock); | ||
174 | return r; | ||
175 | } | ||
176 | |||
177 | static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, | ||
178 | struct omap_dss_audio *audio) | ||
179 | { | ||
180 | unsigned long flags; | ||
181 | int r; | ||
182 | |||
183 | mutex_lock(&hdmi.lock); | ||
184 | spin_lock_irqsave(&hdmi.audio_lock, flags); | ||
185 | |||
186 | /* config audio only if the display is active and supports audio */ | ||
187 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || | ||
188 | !hdmi_mode_has_audio()) { | ||
189 | DSSERR("audio not supported or display is off\n"); | ||
190 | r = -EPERM; | ||
191 | goto err; | ||
192 | } | ||
193 | |||
194 | r = hdmi_audio_config(audio); | ||
195 | |||
196 | if (!r) | ||
197 | dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED; | ||
198 | |||
199 | err: | ||
200 | spin_unlock_irqrestore(&hdmi.audio_lock, flags); | ||
201 | mutex_unlock(&hdmi.lock); | ||
202 | return r; | ||
203 | } | ||
204 | |||
205 | #else | ||
206 | static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) | ||
207 | { | ||
208 | return -EPERM; | ||
209 | } | ||
210 | |||
211 | static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) | ||
212 | { | ||
213 | } | ||
214 | |||
215 | static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) | ||
216 | { | ||
217 | return -EPERM; | ||
218 | } | ||
219 | |||
220 | static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) | ||
221 | { | ||
222 | } | ||
223 | |||
224 | static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) | ||
225 | { | ||
226 | return false; | ||
227 | } | ||
228 | |||
229 | static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, | ||
230 | struct omap_dss_audio *audio) | ||
231 | { | ||
232 | return -EPERM; | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | static int hdmi_panel_enable(struct omap_dss_device *dssdev) | ||
237 | { | ||
238 | int r = 0; | ||
239 | DSSDBG("ENTER hdmi_panel_enable\n"); | ||
240 | |||
241 | mutex_lock(&hdmi.lock); | ||
242 | |||
243 | if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { | ||
244 | r = -EINVAL; | ||
245 | goto err; | ||
246 | } | ||
247 | |||
248 | omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings); | ||
249 | |||
250 | r = omapdss_hdmi_display_enable(dssdev); | ||
251 | if (r) { | ||
252 | DSSERR("failed to power on\n"); | ||
253 | goto err; | ||
254 | } | ||
255 | |||
256 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | ||
257 | |||
258 | err: | ||
259 | mutex_unlock(&hdmi.lock); | ||
260 | |||
261 | return r; | ||
262 | } | ||
263 | |||
264 | static void hdmi_panel_disable(struct omap_dss_device *dssdev) | ||
265 | { | ||
266 | mutex_lock(&hdmi.lock); | ||
267 | |||
268 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | ||
269 | /* | ||
270 | * TODO: notify audio users that the display was disabled. For | ||
271 | * now, disable audio locally to not break our audio state | ||
272 | * machine. | ||
273 | */ | ||
274 | hdmi_panel_audio_disable(dssdev); | ||
275 | omapdss_hdmi_display_disable(dssdev); | ||
276 | } | ||
277 | |||
278 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | ||
279 | |||
280 | mutex_unlock(&hdmi.lock); | ||
281 | } | ||
282 | |||
283 | static void hdmi_get_timings(struct omap_dss_device *dssdev, | ||
284 | struct omap_video_timings *timings) | ||
285 | { | ||
286 | mutex_lock(&hdmi.lock); | ||
287 | |||
288 | *timings = dssdev->panel.timings; | ||
289 | |||
290 | mutex_unlock(&hdmi.lock); | ||
291 | } | ||
292 | |||
293 | static void hdmi_set_timings(struct omap_dss_device *dssdev, | ||
294 | struct omap_video_timings *timings) | ||
295 | { | ||
296 | DSSDBG("hdmi_set_timings\n"); | ||
297 | |||
298 | mutex_lock(&hdmi.lock); | ||
299 | |||
300 | /* | ||
301 | * TODO: notify audio users that there was a timings change. For | ||
302 | * now, disable audio locally to not break our audio state machine. | ||
303 | */ | ||
304 | hdmi_panel_audio_disable(dssdev); | ||
305 | |||
306 | omapdss_hdmi_display_set_timing(dssdev, timings); | ||
307 | dssdev->panel.timings = *timings; | ||
308 | |||
309 | mutex_unlock(&hdmi.lock); | ||
310 | } | ||
311 | |||
312 | static int hdmi_check_timings(struct omap_dss_device *dssdev, | ||
313 | struct omap_video_timings *timings) | ||
314 | { | ||
315 | int r = 0; | ||
316 | |||
317 | DSSDBG("hdmi_check_timings\n"); | ||
318 | |||
319 | mutex_lock(&hdmi.lock); | ||
320 | |||
321 | r = omapdss_hdmi_display_check_timing(dssdev, timings); | ||
322 | |||
323 | mutex_unlock(&hdmi.lock); | ||
324 | return r; | ||
325 | } | ||
326 | |||
327 | static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) | ||
328 | { | ||
329 | int r; | ||
330 | bool need_enable; | ||
331 | |||
332 | mutex_lock(&hdmi.lock); | ||
333 | |||
334 | need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; | ||
335 | |||
336 | if (need_enable) { | ||
337 | r = omapdss_hdmi_core_enable(dssdev); | ||
338 | if (r) | ||
339 | goto err; | ||
340 | } | ||
341 | |||
342 | r = omapdss_hdmi_read_edid(buf, len); | ||
343 | |||
344 | if (need_enable) | ||
345 | omapdss_hdmi_core_disable(dssdev); | ||
346 | err: | ||
347 | mutex_unlock(&hdmi.lock); | ||
348 | |||
349 | return r; | ||
350 | } | ||
351 | |||
352 | static bool hdmi_detect(struct omap_dss_device *dssdev) | ||
353 | { | ||
354 | int r; | ||
355 | bool need_enable; | ||
356 | |||
357 | mutex_lock(&hdmi.lock); | ||
358 | |||
359 | need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; | ||
360 | |||
361 | if (need_enable) { | ||
362 | r = omapdss_hdmi_core_enable(dssdev); | ||
363 | if (r) | ||
364 | goto err; | ||
365 | } | ||
366 | |||
367 | r = omapdss_hdmi_detect(); | ||
368 | |||
369 | if (need_enable) | ||
370 | omapdss_hdmi_core_disable(dssdev); | ||
371 | err: | ||
372 | mutex_unlock(&hdmi.lock); | ||
373 | |||
374 | return r; | ||
375 | } | ||
376 | |||
377 | static struct omap_dss_driver hdmi_driver = { | ||
378 | .probe = hdmi_panel_probe, | ||
379 | .remove = hdmi_panel_remove, | ||
380 | .enable = hdmi_panel_enable, | ||
381 | .disable = hdmi_panel_disable, | ||
382 | .get_timings = hdmi_get_timings, | ||
383 | .set_timings = hdmi_set_timings, | ||
384 | .check_timings = hdmi_check_timings, | ||
385 | .read_edid = hdmi_read_edid, | ||
386 | .detect = hdmi_detect, | ||
387 | .audio_enable = hdmi_panel_audio_enable, | ||
388 | .audio_disable = hdmi_panel_audio_disable, | ||
389 | .audio_start = hdmi_panel_audio_start, | ||
390 | .audio_stop = hdmi_panel_audio_stop, | ||
391 | .audio_supported = hdmi_panel_audio_supported, | ||
392 | .audio_config = hdmi_panel_audio_config, | ||
393 | .driver = { | ||
394 | .name = "hdmi_panel", | ||
395 | .owner = THIS_MODULE, | ||
396 | }, | ||
397 | }; | ||
398 | |||
399 | int hdmi_panel_init(void) | ||
400 | { | ||
401 | mutex_init(&hdmi.lock); | ||
402 | |||
403 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | ||
404 | spin_lock_init(&hdmi.audio_lock); | ||
405 | #endif | ||
406 | |||
407 | return omap_dss_register_driver(&hdmi_driver); | ||
408 | } | ||
409 | |||
410 | void hdmi_panel_exit(void) | ||
411 | { | ||
412 | omap_dss_unregister_driver(&hdmi_driver); | ||
413 | |||
414 | } | ||
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c index de7e7b5b1b7c..37b59fe28dc8 100644 --- a/drivers/video/omap2/dss/manager-sysfs.c +++ b/drivers/video/omap2/dss/manager-sysfs.c | |||
@@ -285,9 +285,10 @@ static ssize_t manager_alpha_blending_enabled_show( | |||
285 | { | 285 | { |
286 | struct omap_overlay_manager_info info; | 286 | struct omap_overlay_manager_info info; |
287 | 287 | ||
288 | mgr->get_manager_info(mgr, &info); | 288 | if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) |
289 | return -ENODEV; | ||
289 | 290 | ||
290 | WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); | 291 | mgr->get_manager_info(mgr, &info); |
291 | 292 | ||
292 | return snprintf(buf, PAGE_SIZE, "%d\n", | 293 | return snprintf(buf, PAGE_SIZE, "%d\n", |
293 | info.partial_alpha_enabled); | 294 | info.partial_alpha_enabled); |
@@ -301,7 +302,8 @@ static ssize_t manager_alpha_blending_enabled_store( | |||
301 | bool enable; | 302 | bool enable; |
302 | int r; | 303 | int r; |
303 | 304 | ||
304 | WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); | 305 | if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) |
306 | return -ENODEV; | ||
305 | 307 | ||
306 | r = strtobool(buf, &enable); | 308 | r = strtobool(buf, &enable); |
307 | if (r) | 309 | if (r) |
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c index 3f5c0a758b32..2ab3afa615e8 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/omap2/dss/output.c | |||
@@ -34,9 +34,9 @@ int omapdss_output_set_device(struct omap_dss_device *out, | |||
34 | 34 | ||
35 | mutex_lock(&output_lock); | 35 | mutex_lock(&output_lock); |
36 | 36 | ||
37 | if (out->device) { | 37 | if (out->dst) { |
38 | DSSERR("output already has device %s connected to it\n", | 38 | DSSERR("output already has device %s connected to it\n", |
39 | out->device->name); | 39 | out->dst->name); |
40 | r = -EINVAL; | 40 | r = -EINVAL; |
41 | goto err; | 41 | goto err; |
42 | } | 42 | } |
@@ -47,8 +47,8 @@ int omapdss_output_set_device(struct omap_dss_device *out, | |||
47 | goto err; | 47 | goto err; |
48 | } | 48 | } |
49 | 49 | ||
50 | out->device = dssdev; | 50 | out->dst = dssdev; |
51 | dssdev->output = out; | 51 | dssdev->src = out; |
52 | 52 | ||
53 | mutex_unlock(&output_lock); | 53 | mutex_unlock(&output_lock); |
54 | 54 | ||
@@ -66,21 +66,21 @@ int omapdss_output_unset_device(struct omap_dss_device *out) | |||
66 | 66 | ||
67 | mutex_lock(&output_lock); | 67 | mutex_lock(&output_lock); |
68 | 68 | ||
69 | if (!out->device) { | 69 | if (!out->dst) { |
70 | DSSERR("output doesn't have a device connected to it\n"); | 70 | DSSERR("output doesn't have a device connected to it\n"); |
71 | r = -EINVAL; | 71 | r = -EINVAL; |
72 | goto err; | 72 | goto err; |
73 | } | 73 | } |
74 | 74 | ||
75 | if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) { | 75 | if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) { |
76 | DSSERR("device %s is not disabled, cannot unset device\n", | 76 | DSSERR("device %s is not disabled, cannot unset device\n", |
77 | out->device->name); | 77 | out->dst->name); |
78 | r = -EINVAL; | 78 | r = -EINVAL; |
79 | goto err; | 79 | goto err; |
80 | } | 80 | } |
81 | 81 | ||
82 | out->device->output = NULL; | 82 | out->dst->src = NULL; |
83 | out->device = NULL; | 83 | out->dst = NULL; |
84 | 84 | ||
85 | mutex_unlock(&output_lock); | 85 | mutex_unlock(&output_lock); |
86 | 86 | ||
@@ -146,8 +146,8 @@ EXPORT_SYMBOL(omap_dss_find_output_by_node); | |||
146 | 146 | ||
147 | struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev) | 147 | struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev) |
148 | { | 148 | { |
149 | while (dssdev->output) | 149 | while (dssdev->src) |
150 | dssdev = dssdev->output; | 150 | dssdev = dssdev->src; |
151 | 151 | ||
152 | if (dssdev->id != 0) | 152 | if (dssdev->id != 0) |
153 | return omap_dss_get_device(dssdev); | 153 | return omap_dss_get_device(dssdev); |
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index fdfe6e6f25df..c8a81a2b879c 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c | |||
@@ -151,19 +151,17 @@ static void rfbi_runtime_put(void) | |||
151 | WARN_ON(r < 0 && r != -ENOSYS); | 151 | WARN_ON(r < 0 && r != -ENOSYS); |
152 | } | 152 | } |
153 | 153 | ||
154 | void rfbi_bus_lock(void) | 154 | static void rfbi_bus_lock(void) |
155 | { | 155 | { |
156 | down(&rfbi.bus_lock); | 156 | down(&rfbi.bus_lock); |
157 | } | 157 | } |
158 | EXPORT_SYMBOL(rfbi_bus_lock); | ||
159 | 158 | ||
160 | void rfbi_bus_unlock(void) | 159 | static void rfbi_bus_unlock(void) |
161 | { | 160 | { |
162 | up(&rfbi.bus_lock); | 161 | up(&rfbi.bus_lock); |
163 | } | 162 | } |
164 | EXPORT_SYMBOL(rfbi_bus_unlock); | ||
165 | 163 | ||
166 | void omap_rfbi_write_command(const void *buf, u32 len) | 164 | static void rfbi_write_command(const void *buf, u32 len) |
167 | { | 165 | { |
168 | switch (rfbi.parallelmode) { | 166 | switch (rfbi.parallelmode) { |
169 | case OMAP_DSS_RFBI_PARALLELMODE_8: | 167 | case OMAP_DSS_RFBI_PARALLELMODE_8: |
@@ -189,9 +187,8 @@ void omap_rfbi_write_command(const void *buf, u32 len) | |||
189 | BUG(); | 187 | BUG(); |
190 | } | 188 | } |
191 | } | 189 | } |
192 | EXPORT_SYMBOL(omap_rfbi_write_command); | ||
193 | 190 | ||
194 | void omap_rfbi_read_data(void *buf, u32 len) | 191 | static void rfbi_read_data(void *buf, u32 len) |
195 | { | 192 | { |
196 | switch (rfbi.parallelmode) { | 193 | switch (rfbi.parallelmode) { |
197 | case OMAP_DSS_RFBI_PARALLELMODE_8: | 194 | case OMAP_DSS_RFBI_PARALLELMODE_8: |
@@ -221,9 +218,8 @@ void omap_rfbi_read_data(void *buf, u32 len) | |||
221 | BUG(); | 218 | BUG(); |
222 | } | 219 | } |
223 | } | 220 | } |
224 | EXPORT_SYMBOL(omap_rfbi_read_data); | ||
225 | 221 | ||
226 | void omap_rfbi_write_data(const void *buf, u32 len) | 222 | static void rfbi_write_data(const void *buf, u32 len) |
227 | { | 223 | { |
228 | switch (rfbi.parallelmode) { | 224 | switch (rfbi.parallelmode) { |
229 | case OMAP_DSS_RFBI_PARALLELMODE_8: | 225 | case OMAP_DSS_RFBI_PARALLELMODE_8: |
@@ -250,9 +246,8 @@ void omap_rfbi_write_data(const void *buf, u32 len) | |||
250 | 246 | ||
251 | } | 247 | } |
252 | } | 248 | } |
253 | EXPORT_SYMBOL(omap_rfbi_write_data); | ||
254 | 249 | ||
255 | void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, | 250 | static void rfbi_write_pixels(const void __iomem *buf, int scr_width, |
256 | u16 x, u16 y, | 251 | u16 x, u16 y, |
257 | u16 w, u16 h) | 252 | u16 w, u16 h) |
258 | { | 253 | { |
@@ -305,7 +300,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, | |||
305 | BUG(); | 300 | BUG(); |
306 | } | 301 | } |
307 | } | 302 | } |
308 | EXPORT_SYMBOL(omap_rfbi_write_pixels); | ||
309 | 303 | ||
310 | static int rfbi_transfer_area(struct omap_dss_device *dssdev, | 304 | static int rfbi_transfer_area(struct omap_dss_device *dssdev, |
311 | void (*callback)(void *data), void *data) | 305 | void (*callback)(void *data), void *data) |
@@ -574,7 +568,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t) | |||
574 | } | 568 | } |
575 | 569 | ||
576 | /* xxx FIX module selection missing */ | 570 | /* xxx FIX module selection missing */ |
577 | int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode, | 571 | static int rfbi_setup_te(enum omap_rfbi_te_mode mode, |
578 | unsigned hs_pulse_time, unsigned vs_pulse_time, | 572 | unsigned hs_pulse_time, unsigned vs_pulse_time, |
579 | int hs_pol_inv, int vs_pol_inv, int extif_div) | 573 | int hs_pol_inv, int vs_pol_inv, int extif_div) |
580 | { | 574 | { |
@@ -613,10 +607,9 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode, | |||
613 | 607 | ||
614 | return 0; | 608 | return 0; |
615 | } | 609 | } |
616 | EXPORT_SYMBOL(omap_rfbi_setup_te); | ||
617 | 610 | ||
618 | /* xxx FIX module selection missing */ | 611 | /* xxx FIX module selection missing */ |
619 | int omap_rfbi_enable_te(bool enable, unsigned line) | 612 | static int rfbi_enable_te(bool enable, unsigned line) |
620 | { | 613 | { |
621 | u32 l; | 614 | u32 l; |
622 | 615 | ||
@@ -636,9 +629,8 @@ int omap_rfbi_enable_te(bool enable, unsigned line) | |||
636 | 629 | ||
637 | return 0; | 630 | return 0; |
638 | } | 631 | } |
639 | EXPORT_SYMBOL(omap_rfbi_enable_te); | ||
640 | 632 | ||
641 | static int rfbi_configure(int rfbi_module, int bpp, int lines) | 633 | static int rfbi_configure_bus(int rfbi_module, int bpp, int lines) |
642 | { | 634 | { |
643 | u32 l; | 635 | u32 l; |
644 | int cycle1 = 0, cycle2 = 0, cycle3 = 0; | 636 | int cycle1 = 0, cycle2 = 0, cycle3 = 0; |
@@ -770,45 +762,39 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines) | |||
770 | return 0; | 762 | return 0; |
771 | } | 763 | } |
772 | 764 | ||
773 | int omap_rfbi_configure(struct omap_dss_device *dssdev) | 765 | static int rfbi_configure(struct omap_dss_device *dssdev) |
774 | { | 766 | { |
775 | return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size, | 767 | return rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size, |
776 | rfbi.data_lines); | 768 | rfbi.data_lines); |
777 | } | 769 | } |
778 | EXPORT_SYMBOL(omap_rfbi_configure); | ||
779 | 770 | ||
780 | int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *), | 771 | static int rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *), |
781 | void *data) | 772 | void *data) |
782 | { | 773 | { |
783 | return rfbi_transfer_area(dssdev, callback, data); | 774 | return rfbi_transfer_area(dssdev, callback, data); |
784 | } | 775 | } |
785 | EXPORT_SYMBOL(omap_rfbi_update); | ||
786 | 776 | ||
787 | void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) | 777 | static void rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) |
788 | { | 778 | { |
789 | rfbi.timings.x_res = w; | 779 | rfbi.timings.x_res = w; |
790 | rfbi.timings.y_res = h; | 780 | rfbi.timings.y_res = h; |
791 | } | 781 | } |
792 | EXPORT_SYMBOL(omapdss_rfbi_set_size); | ||
793 | 782 | ||
794 | void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size) | 783 | static void rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size) |
795 | { | 784 | { |
796 | rfbi.pixel_size = pixel_size; | 785 | rfbi.pixel_size = pixel_size; |
797 | } | 786 | } |
798 | EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size); | ||
799 | 787 | ||
800 | void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) | 788 | static void rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) |
801 | { | 789 | { |
802 | rfbi.data_lines = data_lines; | 790 | rfbi.data_lines = data_lines; |
803 | } | 791 | } |
804 | EXPORT_SYMBOL(omapdss_rfbi_set_data_lines); | ||
805 | 792 | ||
806 | void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev, | 793 | static void rfbi_set_interface_timings(struct omap_dss_device *dssdev, |
807 | struct rfbi_timings *timings) | 794 | struct rfbi_timings *timings) |
808 | { | 795 | { |
809 | rfbi.intf_timings = *timings; | 796 | rfbi.intf_timings = *timings; |
810 | } | 797 | } |
811 | EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings); | ||
812 | 798 | ||
813 | static void rfbi_dump_regs(struct seq_file *s) | 799 | static void rfbi_dump_regs(struct seq_file *s) |
814 | { | 800 | { |
@@ -888,7 +874,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) | |||
888 | dss_mgr_set_timings(mgr, &rfbi.timings); | 874 | dss_mgr_set_timings(mgr, &rfbi.timings); |
889 | } | 875 | } |
890 | 876 | ||
891 | int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) | 877 | static int rfbi_display_enable(struct omap_dss_device *dssdev) |
892 | { | 878 | { |
893 | struct omap_dss_device *out = &rfbi.output; | 879 | struct omap_dss_device *out = &rfbi.output; |
894 | int r; | 880 | int r; |
@@ -911,7 +897,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) | |||
911 | 897 | ||
912 | rfbi_config_lcd_manager(dssdev); | 898 | rfbi_config_lcd_manager(dssdev); |
913 | 899 | ||
914 | rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size, | 900 | rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size, |
915 | rfbi.data_lines); | 901 | rfbi.data_lines); |
916 | 902 | ||
917 | rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings); | 903 | rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings); |
@@ -921,9 +907,8 @@ err1: | |||
921 | rfbi_runtime_put(); | 907 | rfbi_runtime_put(); |
922 | return r; | 908 | return r; |
923 | } | 909 | } |
924 | EXPORT_SYMBOL(omapdss_rfbi_display_enable); | ||
925 | 910 | ||
926 | void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) | 911 | static void rfbi_display_disable(struct omap_dss_device *dssdev) |
927 | { | 912 | { |
928 | struct omap_dss_device *out = &rfbi.output; | 913 | struct omap_dss_device *out = &rfbi.output; |
929 | 914 | ||
@@ -932,7 +917,6 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) | |||
932 | 917 | ||
933 | rfbi_runtime_put(); | 918 | rfbi_runtime_put(); |
934 | } | 919 | } |
935 | EXPORT_SYMBOL(omapdss_rfbi_display_disable); | ||
936 | 920 | ||
937 | static int rfbi_init_display(struct omap_dss_device *dssdev) | 921 | static int rfbi_init_display(struct omap_dss_device *dssdev) |
938 | { | 922 | { |
@@ -940,77 +924,6 @@ static int rfbi_init_display(struct omap_dss_device *dssdev) | |||
940 | return 0; | 924 | return 0; |
941 | } | 925 | } |
942 | 926 | ||
943 | static struct omap_dss_device *rfbi_find_dssdev(struct platform_device *pdev) | ||
944 | { | ||
945 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
946 | const char *def_disp_name = omapdss_get_default_display_name(); | ||
947 | struct omap_dss_device *def_dssdev; | ||
948 | int i; | ||
949 | |||
950 | def_dssdev = NULL; | ||
951 | |||
952 | for (i = 0; i < pdata->num_devices; ++i) { | ||
953 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
954 | |||
955 | if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) | ||
956 | continue; | ||
957 | |||
958 | if (def_dssdev == NULL) | ||
959 | def_dssdev = dssdev; | ||
960 | |||
961 | if (def_disp_name != NULL && | ||
962 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
963 | def_dssdev = dssdev; | ||
964 | break; | ||
965 | } | ||
966 | } | ||
967 | |||
968 | return def_dssdev; | ||
969 | } | ||
970 | |||
971 | static int rfbi_probe_pdata(struct platform_device *rfbidev) | ||
972 | { | ||
973 | struct omap_dss_device *plat_dssdev; | ||
974 | struct omap_dss_device *dssdev; | ||
975 | int r; | ||
976 | |||
977 | plat_dssdev = rfbi_find_dssdev(rfbidev); | ||
978 | |||
979 | if (!plat_dssdev) | ||
980 | return 0; | ||
981 | |||
982 | dssdev = dss_alloc_and_init_device(&rfbidev->dev); | ||
983 | if (!dssdev) | ||
984 | return -ENOMEM; | ||
985 | |||
986 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
987 | |||
988 | r = rfbi_init_display(dssdev); | ||
989 | if (r) { | ||
990 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
991 | dss_put_device(dssdev); | ||
992 | return r; | ||
993 | } | ||
994 | |||
995 | r = omapdss_output_set_device(&rfbi.output, dssdev); | ||
996 | if (r) { | ||
997 | DSSERR("failed to connect output to new device: %s\n", | ||
998 | dssdev->name); | ||
999 | dss_put_device(dssdev); | ||
1000 | return r; | ||
1001 | } | ||
1002 | |||
1003 | r = dss_add_device(dssdev); | ||
1004 | if (r) { | ||
1005 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
1006 | omapdss_output_unset_device(&rfbi.output); | ||
1007 | dss_put_device(dssdev); | ||
1008 | return r; | ||
1009 | } | ||
1010 | |||
1011 | return 0; | ||
1012 | } | ||
1013 | |||
1014 | static void rfbi_init_output(struct platform_device *pdev) | 927 | static void rfbi_init_output(struct platform_device *pdev) |
1015 | { | 928 | { |
1016 | struct omap_dss_device *out = &rfbi.output; | 929 | struct omap_dss_device *out = &rfbi.output; |
@@ -1085,16 +998,8 @@ static int omap_rfbihw_probe(struct platform_device *pdev) | |||
1085 | 998 | ||
1086 | rfbi_init_output(pdev); | 999 | rfbi_init_output(pdev); |
1087 | 1000 | ||
1088 | if (pdev->dev.platform_data) { | ||
1089 | r = rfbi_probe_pdata(pdev); | ||
1090 | if (r) | ||
1091 | goto err_probe; | ||
1092 | } | ||
1093 | |||
1094 | return 0; | 1001 | return 0; |
1095 | 1002 | ||
1096 | err_probe: | ||
1097 | rfbi_uninit_output(pdev); | ||
1098 | err_runtime_get: | 1003 | err_runtime_get: |
1099 | pm_runtime_disable(&pdev->dev); | 1004 | pm_runtime_disable(&pdev->dev); |
1100 | return r; | 1005 | return r; |
@@ -1102,8 +1007,6 @@ err_runtime_get: | |||
1102 | 1007 | ||
1103 | static int __exit omap_rfbihw_remove(struct platform_device *pdev) | 1008 | static int __exit omap_rfbihw_remove(struct platform_device *pdev) |
1104 | { | 1009 | { |
1105 | dss_unregister_child_devices(&pdev->dev); | ||
1106 | |||
1107 | rfbi_uninit_output(pdev); | 1010 | rfbi_uninit_output(pdev); |
1108 | 1011 | ||
1109 | pm_runtime_disable(&pdev->dev); | 1012 | pm_runtime_disable(&pdev->dev); |
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 856af2e89760..ccc569ae7cca 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c | |||
@@ -124,7 +124,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) | |||
124 | dss_mgr_set_lcd_config(mgr, &sdi.mgr_config); | 124 | dss_mgr_set_lcd_config(mgr, &sdi.mgr_config); |
125 | } | 125 | } |
126 | 126 | ||
127 | int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | 127 | static int sdi_display_enable(struct omap_dss_device *dssdev) |
128 | { | 128 | { |
129 | struct omap_dss_device *out = &sdi.output; | 129 | struct omap_dss_device *out = &sdi.output; |
130 | struct omap_video_timings *t = &sdi.timings; | 130 | struct omap_video_timings *t = &sdi.timings; |
@@ -211,9 +211,8 @@ err_get_dispc: | |||
211 | err_reg_enable: | 211 | err_reg_enable: |
212 | return r; | 212 | return r; |
213 | } | 213 | } |
214 | EXPORT_SYMBOL(omapdss_sdi_display_enable); | ||
215 | 214 | ||
216 | void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) | 215 | static void sdi_display_disable(struct omap_dss_device *dssdev) |
217 | { | 216 | { |
218 | struct omap_overlay_manager *mgr = sdi.output.manager; | 217 | struct omap_overlay_manager *mgr = sdi.output.manager; |
219 | 218 | ||
@@ -225,14 +224,12 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) | |||
225 | 224 | ||
226 | regulator_disable(sdi.vdds_sdi_reg); | 225 | regulator_disable(sdi.vdds_sdi_reg); |
227 | } | 226 | } |
228 | EXPORT_SYMBOL(omapdss_sdi_display_disable); | ||
229 | 227 | ||
230 | void omapdss_sdi_set_timings(struct omap_dss_device *dssdev, | 228 | static void sdi_set_timings(struct omap_dss_device *dssdev, |
231 | struct omap_video_timings *timings) | 229 | struct omap_video_timings *timings) |
232 | { | 230 | { |
233 | sdi.timings = *timings; | 231 | sdi.timings = *timings; |
234 | } | 232 | } |
235 | EXPORT_SYMBOL(omapdss_sdi_set_timings); | ||
236 | 233 | ||
237 | static void sdi_get_timings(struct omap_dss_device *dssdev, | 234 | static void sdi_get_timings(struct omap_dss_device *dssdev, |
238 | struct omap_video_timings *timings) | 235 | struct omap_video_timings *timings) |
@@ -254,11 +251,10 @@ static int sdi_check_timings(struct omap_dss_device *dssdev, | |||
254 | return 0; | 251 | return 0; |
255 | } | 252 | } |
256 | 253 | ||
257 | void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs) | 254 | static void sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs) |
258 | { | 255 | { |
259 | sdi.datapairs = datapairs; | 256 | sdi.datapairs = datapairs; |
260 | } | 257 | } |
261 | EXPORT_SYMBOL(omapdss_sdi_set_datapairs); | ||
262 | 258 | ||
263 | static int sdi_init_regulator(void) | 259 | static int sdi_init_regulator(void) |
264 | { | 260 | { |
@@ -267,14 +263,10 @@ static int sdi_init_regulator(void) | |||
267 | if (sdi.vdds_sdi_reg) | 263 | if (sdi.vdds_sdi_reg) |
268 | return 0; | 264 | return 0; |
269 | 265 | ||
270 | vdds_sdi = dss_get_vdds_sdi(); | 266 | vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi"); |
271 | |||
272 | if (IS_ERR(vdds_sdi)) { | 267 | if (IS_ERR(vdds_sdi)) { |
273 | vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi"); | 268 | DSSERR("can't get VDDS_SDI regulator\n"); |
274 | if (IS_ERR(vdds_sdi)) { | 269 | return PTR_ERR(vdds_sdi); |
275 | DSSERR("can't get VDDS_SDI regulator\n"); | ||
276 | return PTR_ERR(vdds_sdi); | ||
277 | } | ||
278 | } | 270 | } |
279 | 271 | ||
280 | sdi.vdds_sdi_reg = vdds_sdi; | 272 | sdi.vdds_sdi_reg = vdds_sdi; |
@@ -282,77 +274,6 @@ static int sdi_init_regulator(void) | |||
282 | return 0; | 274 | return 0; |
283 | } | 275 | } |
284 | 276 | ||
285 | static struct omap_dss_device *sdi_find_dssdev(struct platform_device *pdev) | ||
286 | { | ||
287 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
288 | const char *def_disp_name = omapdss_get_default_display_name(); | ||
289 | struct omap_dss_device *def_dssdev; | ||
290 | int i; | ||
291 | |||
292 | def_dssdev = NULL; | ||
293 | |||
294 | for (i = 0; i < pdata->num_devices; ++i) { | ||
295 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
296 | |||
297 | if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) | ||
298 | continue; | ||
299 | |||
300 | if (def_dssdev == NULL) | ||
301 | def_dssdev = dssdev; | ||
302 | |||
303 | if (def_disp_name != NULL && | ||
304 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
305 | def_dssdev = dssdev; | ||
306 | break; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | return def_dssdev; | ||
311 | } | ||
312 | |||
313 | static int sdi_probe_pdata(struct platform_device *sdidev) | ||
314 | { | ||
315 | struct omap_dss_device *plat_dssdev; | ||
316 | struct omap_dss_device *dssdev; | ||
317 | int r; | ||
318 | |||
319 | plat_dssdev = sdi_find_dssdev(sdidev); | ||
320 | |||
321 | if (!plat_dssdev) | ||
322 | return 0; | ||
323 | |||
324 | dssdev = dss_alloc_and_init_device(&sdidev->dev); | ||
325 | if (!dssdev) | ||
326 | return -ENOMEM; | ||
327 | |||
328 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
329 | |||
330 | r = sdi_init_regulator(); | ||
331 | if (r) { | ||
332 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
333 | dss_put_device(dssdev); | ||
334 | return r; | ||
335 | } | ||
336 | |||
337 | r = omapdss_output_set_device(&sdi.output, dssdev); | ||
338 | if (r) { | ||
339 | DSSERR("failed to connect output to new device: %s\n", | ||
340 | dssdev->name); | ||
341 | dss_put_device(dssdev); | ||
342 | return r; | ||
343 | } | ||
344 | |||
345 | r = dss_add_device(dssdev); | ||
346 | if (r) { | ||
347 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
348 | omapdss_output_unset_device(&sdi.output); | ||
349 | dss_put_device(dssdev); | ||
350 | return r; | ||
351 | } | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int sdi_connect(struct omap_dss_device *dssdev, | 277 | static int sdi_connect(struct omap_dss_device *dssdev, |
357 | struct omap_dss_device *dst) | 278 | struct omap_dss_device *dst) |
358 | { | 279 | { |
@@ -385,9 +306,9 @@ static int sdi_connect(struct omap_dss_device *dssdev, | |||
385 | static void sdi_disconnect(struct omap_dss_device *dssdev, | 306 | static void sdi_disconnect(struct omap_dss_device *dssdev, |
386 | struct omap_dss_device *dst) | 307 | struct omap_dss_device *dst) |
387 | { | 308 | { |
388 | WARN_ON(dst != dssdev->device); | 309 | WARN_ON(dst != dssdev->dst); |
389 | 310 | ||
390 | if (dst != dssdev->device) | 311 | if (dst != dssdev->dst) |
391 | return; | 312 | return; |
392 | 313 | ||
393 | omapdss_output_unset_device(dssdev); | 314 | omapdss_output_unset_device(dssdev); |
@@ -400,14 +321,14 @@ static const struct omapdss_sdi_ops sdi_ops = { | |||
400 | .connect = sdi_connect, | 321 | .connect = sdi_connect, |
401 | .disconnect = sdi_disconnect, | 322 | .disconnect = sdi_disconnect, |
402 | 323 | ||
403 | .enable = omapdss_sdi_display_enable, | 324 | .enable = sdi_display_enable, |
404 | .disable = omapdss_sdi_display_disable, | 325 | .disable = sdi_display_disable, |
405 | 326 | ||
406 | .check_timings = sdi_check_timings, | 327 | .check_timings = sdi_check_timings, |
407 | .set_timings = omapdss_sdi_set_timings, | 328 | .set_timings = sdi_set_timings, |
408 | .get_timings = sdi_get_timings, | 329 | .get_timings = sdi_get_timings, |
409 | 330 | ||
410 | .set_datapairs = omapdss_sdi_set_datapairs, | 331 | .set_datapairs = sdi_set_datapairs, |
411 | }; | 332 | }; |
412 | 333 | ||
413 | static void sdi_init_output(struct platform_device *pdev) | 334 | static void sdi_init_output(struct platform_device *pdev) |
@@ -434,29 +355,15 @@ static void __exit sdi_uninit_output(struct platform_device *pdev) | |||
434 | 355 | ||
435 | static int omap_sdi_probe(struct platform_device *pdev) | 356 | static int omap_sdi_probe(struct platform_device *pdev) |
436 | { | 357 | { |
437 | int r; | ||
438 | |||
439 | sdi.pdev = pdev; | 358 | sdi.pdev = pdev; |
440 | 359 | ||
441 | sdi_init_output(pdev); | 360 | sdi_init_output(pdev); |
442 | 361 | ||
443 | if (pdev->dev.platform_data) { | ||
444 | r = sdi_probe_pdata(pdev); | ||
445 | if (r) | ||
446 | goto err_probe; | ||
447 | } | ||
448 | |||
449 | return 0; | 362 | return 0; |
450 | |||
451 | err_probe: | ||
452 | sdi_uninit_output(pdev); | ||
453 | return r; | ||
454 | } | 363 | } |
455 | 364 | ||
456 | static int __exit omap_sdi_remove(struct platform_device *pdev) | 365 | static int __exit omap_sdi_remove(struct platform_device *pdev) |
457 | { | 366 | { |
458 | dss_unregister_child_devices(&pdev->dev); | ||
459 | |||
460 | sdi_uninit_output(pdev); | 367 | sdi_uninit_output(pdev); |
461 | 368 | ||
462 | return 0; | 369 | return 0; |
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index e242ed85cb07..3dfe00956a4f 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | |||
@@ -779,16 +779,14 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) | |||
779 | struct omap_video_timings video_timing; | 779 | struct omap_video_timings video_timing; |
780 | struct hdmi_video_format video_format; | 780 | struct hdmi_video_format video_format; |
781 | /* HDMI core */ | 781 | /* HDMI core */ |
782 | struct hdmi_core_infoframe_avi avi_cfg = ip_data->avi_cfg; | 782 | struct hdmi_core_infoframe_avi *avi_cfg = &ip_data->avi_cfg; |
783 | struct hdmi_core_video_config v_core_cfg; | 783 | struct hdmi_core_video_config v_core_cfg; |
784 | struct hdmi_core_packet_enable_repeat repeat_cfg; | 784 | struct hdmi_core_packet_enable_repeat repeat_cfg; |
785 | struct hdmi_config *cfg = &ip_data->cfg; | 785 | struct hdmi_config *cfg = &ip_data->cfg; |
786 | 786 | ||
787 | hdmi_wp_init(&video_timing, &video_format); | 787 | hdmi_wp_init(&video_timing, &video_format); |
788 | 788 | ||
789 | hdmi_core_init(&v_core_cfg, | 789 | hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); |
790 | &avi_cfg, | ||
791 | &repeat_cfg); | ||
792 | 790 | ||
793 | hdmi_wp_video_init_format(&video_format, &video_timing, cfg); | 791 | hdmi_wp_video_init_format(&video_format, &video_timing, cfg); |
794 | 792 | ||
@@ -822,24 +820,24 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) | |||
822 | * configure packet | 820 | * configure packet |
823 | * info frame video see doc CEA861-D page 65 | 821 | * info frame video see doc CEA861-D page 65 |
824 | */ | 822 | */ |
825 | avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; | 823 | avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; |
826 | avi_cfg.db1_active_info = | 824 | avi_cfg->db1_active_info = |
827 | HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; | 825 | HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; |
828 | avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; | 826 | avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; |
829 | avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; | 827 | avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; |
830 | avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; | 828 | avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; |
831 | avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; | 829 | avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; |
832 | avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; | 830 | avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; |
833 | avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; | 831 | avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; |
834 | avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; | 832 | avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; |
835 | avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; | 833 | avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; |
836 | avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; | 834 | avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; |
837 | avi_cfg.db4_videocode = cfg->cm.code; | 835 | avi_cfg->db4_videocode = cfg->cm.code; |
838 | avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; | 836 | avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; |
839 | avi_cfg.db6_7_line_eoftop = 0; | 837 | avi_cfg->db6_7_line_eoftop = 0; |
840 | avi_cfg.db8_9_line_sofbottom = 0; | 838 | avi_cfg->db8_9_line_sofbottom = 0; |
841 | avi_cfg.db10_11_pixel_eofleft = 0; | 839 | avi_cfg->db10_11_pixel_eofleft = 0; |
842 | avi_cfg.db12_13_pixel_sofright = 0; | 840 | avi_cfg->db12_13_pixel_sofright = 0; |
843 | 841 | ||
844 | hdmi_core_aux_infoframe_avi_config(ip_data); | 842 | hdmi_core_aux_infoframe_avi_config(ip_data); |
845 | 843 | ||
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 496a106fe823..5f88ac47b7fa 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c | |||
@@ -492,7 +492,7 @@ static void venc_power_off(struct omap_dss_device *dssdev) | |||
492 | venc_runtime_put(); | 492 | venc_runtime_put(); |
493 | } | 493 | } |
494 | 494 | ||
495 | int omapdss_venc_display_enable(struct omap_dss_device *dssdev) | 495 | static int venc_display_enable(struct omap_dss_device *dssdev) |
496 | { | 496 | { |
497 | struct omap_dss_device *out = &venc.output; | 497 | struct omap_dss_device *out = &venc.output; |
498 | int r; | 498 | int r; |
@@ -521,7 +521,7 @@ err0: | |||
521 | return r; | 521 | return r; |
522 | } | 522 | } |
523 | 523 | ||
524 | void omapdss_venc_display_disable(struct omap_dss_device *dssdev) | 524 | static void venc_display_disable(struct omap_dss_device *dssdev) |
525 | { | 525 | { |
526 | DSSDBG("venc_display_disable\n"); | 526 | DSSDBG("venc_display_disable\n"); |
527 | 527 | ||
@@ -532,7 +532,7 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev) | |||
532 | mutex_unlock(&venc.venc_lock); | 532 | mutex_unlock(&venc.venc_lock); |
533 | } | 533 | } |
534 | 534 | ||
535 | void omapdss_venc_set_timings(struct omap_dss_device *dssdev, | 535 | static void venc_set_timings(struct omap_dss_device *dssdev, |
536 | struct omap_video_timings *timings) | 536 | struct omap_video_timings *timings) |
537 | { | 537 | { |
538 | DSSDBG("venc_set_timings\n"); | 538 | DSSDBG("venc_set_timings\n"); |
@@ -550,7 +550,7 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev, | |||
550 | mutex_unlock(&venc.venc_lock); | 550 | mutex_unlock(&venc.venc_lock); |
551 | } | 551 | } |
552 | 552 | ||
553 | int omapdss_venc_check_timings(struct omap_dss_device *dssdev, | 553 | static int venc_check_timings(struct omap_dss_device *dssdev, |
554 | struct omap_video_timings *timings) | 554 | struct omap_video_timings *timings) |
555 | { | 555 | { |
556 | DSSDBG("venc_check_timings\n"); | 556 | DSSDBG("venc_check_timings\n"); |
@@ -574,13 +574,13 @@ static void venc_get_timings(struct omap_dss_device *dssdev, | |||
574 | mutex_unlock(&venc.venc_lock); | 574 | mutex_unlock(&venc.venc_lock); |
575 | } | 575 | } |
576 | 576 | ||
577 | u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev) | 577 | static u32 venc_get_wss(struct omap_dss_device *dssdev) |
578 | { | 578 | { |
579 | /* Invert due to VENC_L21_WC_CTL:INV=1 */ | 579 | /* Invert due to VENC_L21_WC_CTL:INV=1 */ |
580 | return (venc.wss_data >> 8) ^ 0xfffff; | 580 | return (venc.wss_data >> 8) ^ 0xfffff; |
581 | } | 581 | } |
582 | 582 | ||
583 | int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss) | 583 | static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) |
584 | { | 584 | { |
585 | const struct venc_config *config; | 585 | const struct venc_config *config; |
586 | int r; | 586 | int r; |
@@ -609,7 +609,7 @@ err: | |||
609 | return r; | 609 | return r; |
610 | } | 610 | } |
611 | 611 | ||
612 | void omapdss_venc_set_type(struct omap_dss_device *dssdev, | 612 | static void venc_set_type(struct omap_dss_device *dssdev, |
613 | enum omap_dss_venc_type type) | 613 | enum omap_dss_venc_type type) |
614 | { | 614 | { |
615 | mutex_lock(&venc.venc_lock); | 615 | mutex_lock(&venc.venc_lock); |
@@ -619,7 +619,7 @@ void omapdss_venc_set_type(struct omap_dss_device *dssdev, | |||
619 | mutex_unlock(&venc.venc_lock); | 619 | mutex_unlock(&venc.venc_lock); |
620 | } | 620 | } |
621 | 621 | ||
622 | void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, | 622 | static void venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, |
623 | bool invert_polarity) | 623 | bool invert_polarity) |
624 | { | 624 | { |
625 | mutex_lock(&venc.venc_lock); | 625 | mutex_lock(&venc.venc_lock); |
@@ -721,74 +721,6 @@ static int venc_get_clocks(struct platform_device *pdev) | |||
721 | return 0; | 721 | return 0; |
722 | } | 722 | } |
723 | 723 | ||
724 | static struct omap_dss_device *venc_find_dssdev(struct platform_device *pdev) | ||
725 | { | ||
726 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; | ||
727 | const char *def_disp_name = omapdss_get_default_display_name(); | ||
728 | struct omap_dss_device *def_dssdev; | ||
729 | int i; | ||
730 | |||
731 | def_dssdev = NULL; | ||
732 | |||
733 | for (i = 0; i < pdata->num_devices; ++i) { | ||
734 | struct omap_dss_device *dssdev = pdata->devices[i]; | ||
735 | |||
736 | if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) | ||
737 | continue; | ||
738 | |||
739 | if (def_dssdev == NULL) | ||
740 | def_dssdev = dssdev; | ||
741 | |||
742 | if (def_disp_name != NULL && | ||
743 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
744 | def_dssdev = dssdev; | ||
745 | break; | ||
746 | } | ||
747 | } | ||
748 | |||
749 | return def_dssdev; | ||
750 | } | ||
751 | |||
752 | static int venc_probe_pdata(struct platform_device *vencdev) | ||
753 | { | ||
754 | struct omap_dss_device *plat_dssdev; | ||
755 | struct omap_dss_device *dssdev; | ||
756 | int r; | ||
757 | |||
758 | plat_dssdev = venc_find_dssdev(vencdev); | ||
759 | |||
760 | if (!plat_dssdev) | ||
761 | return 0; | ||
762 | |||
763 | r = venc_init_regulator(); | ||
764 | if (r) | ||
765 | return r; | ||
766 | |||
767 | dssdev = dss_alloc_and_init_device(&vencdev->dev); | ||
768 | if (!dssdev) | ||
769 | return -ENOMEM; | ||
770 | |||
771 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
772 | |||
773 | r = omapdss_output_set_device(&venc.output, dssdev); | ||
774 | if (r) { | ||
775 | DSSERR("failed to connect output to new device: %s\n", | ||
776 | dssdev->name); | ||
777 | dss_put_device(dssdev); | ||
778 | return r; | ||
779 | } | ||
780 | |||
781 | r = dss_add_device(dssdev); | ||
782 | if (r) { | ||
783 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
784 | omapdss_output_unset_device(&venc.output); | ||
785 | dss_put_device(dssdev); | ||
786 | return r; | ||
787 | } | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static int venc_connect(struct omap_dss_device *dssdev, | 724 | static int venc_connect(struct omap_dss_device *dssdev, |
793 | struct omap_dss_device *dst) | 725 | struct omap_dss_device *dst) |
794 | { | 726 | { |
@@ -821,9 +753,9 @@ static int venc_connect(struct omap_dss_device *dssdev, | |||
821 | static void venc_disconnect(struct omap_dss_device *dssdev, | 753 | static void venc_disconnect(struct omap_dss_device *dssdev, |
822 | struct omap_dss_device *dst) | 754 | struct omap_dss_device *dst) |
823 | { | 755 | { |
824 | WARN_ON(dst != dssdev->device); | 756 | WARN_ON(dst != dssdev->dst); |
825 | 757 | ||
826 | if (dst != dssdev->device) | 758 | if (dst != dssdev->dst) |
827 | return; | 759 | return; |
828 | 760 | ||
829 | omapdss_output_unset_device(dssdev); | 761 | omapdss_output_unset_device(dssdev); |
@@ -836,18 +768,18 @@ static const struct omapdss_atv_ops venc_ops = { | |||
836 | .connect = venc_connect, | 768 | .connect = venc_connect, |
837 | .disconnect = venc_disconnect, | 769 | .disconnect = venc_disconnect, |
838 | 770 | ||
839 | .enable = omapdss_venc_display_enable, | 771 | .enable = venc_display_enable, |
840 | .disable = omapdss_venc_display_disable, | 772 | .disable = venc_display_disable, |
841 | 773 | ||
842 | .check_timings = omapdss_venc_check_timings, | 774 | .check_timings = venc_check_timings, |
843 | .set_timings = omapdss_venc_set_timings, | 775 | .set_timings = venc_set_timings, |
844 | .get_timings = venc_get_timings, | 776 | .get_timings = venc_get_timings, |
845 | 777 | ||
846 | .set_type = omapdss_venc_set_type, | 778 | .set_type = venc_set_type, |
847 | .invert_vid_out_polarity = omapdss_venc_invert_vid_out_polarity, | 779 | .invert_vid_out_polarity = venc_invert_vid_out_polarity, |
848 | 780 | ||
849 | .set_wss = omapdss_venc_set_wss, | 781 | .set_wss = venc_set_wss, |
850 | .get_wss = omapdss_venc_get_wss, | 782 | .get_wss = venc_get_wss, |
851 | }; | 783 | }; |
852 | 784 | ||
853 | static void venc_init_output(struct platform_device *pdev) | 785 | static void venc_init_output(struct platform_device *pdev) |
@@ -913,26 +845,12 @@ static int omap_venchw_probe(struct platform_device *pdev) | |||
913 | 845 | ||
914 | venc_runtime_put(); | 846 | venc_runtime_put(); |
915 | 847 | ||
916 | r = venc_panel_init(); | ||
917 | if (r) | ||
918 | goto err_panel_init; | ||
919 | |||
920 | dss_debugfs_create_file("venc", venc_dump_regs); | 848 | dss_debugfs_create_file("venc", venc_dump_regs); |
921 | 849 | ||
922 | venc_init_output(pdev); | 850 | venc_init_output(pdev); |
923 | 851 | ||
924 | if (pdev->dev.platform_data) { | ||
925 | r = venc_probe_pdata(pdev); | ||
926 | if (r) | ||
927 | goto err_probe; | ||
928 | } | ||
929 | |||
930 | return 0; | 852 | return 0; |
931 | 853 | ||
932 | err_probe: | ||
933 | venc_panel_exit(); | ||
934 | venc_uninit_output(pdev); | ||
935 | err_panel_init: | ||
936 | err_runtime_get: | 854 | err_runtime_get: |
937 | pm_runtime_disable(&pdev->dev); | 855 | pm_runtime_disable(&pdev->dev); |
938 | return r; | 856 | return r; |
@@ -940,10 +858,6 @@ err_runtime_get: | |||
940 | 858 | ||
941 | static int __exit omap_venchw_remove(struct platform_device *pdev) | 859 | static int __exit omap_venchw_remove(struct platform_device *pdev) |
942 | { | 860 | { |
943 | dss_unregister_child_devices(&pdev->dev); | ||
944 | |||
945 | venc_panel_exit(); | ||
946 | |||
947 | venc_uninit_output(pdev); | 861 | venc_uninit_output(pdev); |
948 | 862 | ||
949 | pm_runtime_disable(&pdev->dev); | 863 | pm_runtime_disable(&pdev->dev); |
diff --git a/drivers/video/output.c b/drivers/video/output.c index 6285b9718451..1446c49fe6af 100644 --- a/drivers/video/output.c +++ b/drivers/video/output.c | |||
@@ -32,8 +32,8 @@ MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction"); | |||
32 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
33 | MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); | 33 | MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); |
34 | 34 | ||
35 | static ssize_t video_output_show_state(struct device *dev, | 35 | static ssize_t state_show(struct device *dev, struct device_attribute *attr, |
36 | struct device_attribute *attr, char *buf) | 36 | char *buf) |
37 | { | 37 | { |
38 | ssize_t ret_size = 0; | 38 | ssize_t ret_size = 0; |
39 | struct output_device *od = to_output_device(dev); | 39 | struct output_device *od = to_output_device(dev); |
@@ -42,9 +42,8 @@ static ssize_t video_output_show_state(struct device *dev, | |||
42 | return ret_size; | 42 | return ret_size; |
43 | } | 43 | } |
44 | 44 | ||
45 | static ssize_t video_output_store_state(struct device *dev, | 45 | static ssize_t state_store(struct device *dev, struct device_attribute *attr, |
46 | struct device_attribute *attr, | 46 | const char *buf,size_t count) |
47 | const char *buf,size_t count) | ||
48 | { | 47 | { |
49 | char *endp; | 48 | char *endp; |
50 | struct output_device *od = to_output_device(dev); | 49 | struct output_device *od = to_output_device(dev); |
@@ -62,6 +61,7 @@ static ssize_t video_output_store_state(struct device *dev, | |||
62 | } | 61 | } |
63 | return count; | 62 | return count; |
64 | } | 63 | } |
64 | static DEVICE_ATTR_RW(state); | ||
65 | 65 | ||
66 | static void video_output_release(struct device *dev) | 66 | static void video_output_release(struct device *dev) |
67 | { | 67 | { |
@@ -69,16 +69,16 @@ static void video_output_release(struct device *dev) | |||
69 | kfree(od); | 69 | kfree(od); |
70 | } | 70 | } |
71 | 71 | ||
72 | static struct device_attribute video_output_attributes[] = { | 72 | static struct attribute *video_output_attrs[] = { |
73 | __ATTR(state, 0644, video_output_show_state, video_output_store_state), | 73 | &dev_attr_state.attr, |
74 | __ATTR_NULL, | 74 | NULL, |
75 | }; | 75 | }; |
76 | 76 | ATTRIBUTE_GROUPS(video_output); | |
77 | 77 | ||
78 | static struct class video_output_class = { | 78 | static struct class video_output_class = { |
79 | .name = "video_output", | 79 | .name = "video_output", |
80 | .dev_release = video_output_release, | 80 | .dev_release = video_output_release, |
81 | .dev_attrs = video_output_attributes, | 81 | .dev_groups = video_output_groups, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | struct output_device *video_output_register(const char *name, | 84 | struct output_device *video_output_register(const char *name, |
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index b2a8912f6435..a9ac3ce2d0e9 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c | |||
@@ -713,7 +713,7 @@ static int sgivwfb_mmap(struct fb_info *info, | |||
713 | r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size); | 713 | r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size); |
714 | 714 | ||
715 | printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", | 715 | printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", |
716 | offset, vma->vm_start); | 716 | sgivwfb_mem_phys + (vma->vm_pgoff << PAGE_SHIFT), vma->vm_start); |
717 | 717 | ||
718 | return r; | 718 | return r; |
719 | } | 719 | } |
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c index a8c6c43a4658..1265b25f9f99 100644 --- a/drivers/video/sh7760fb.c +++ b/drivers/video/sh7760fb.c | |||
@@ -567,7 +567,7 @@ static int sh7760fb_remove(struct platform_device *dev) | |||
567 | fb_dealloc_cmap(&info->cmap); | 567 | fb_dealloc_cmap(&info->cmap); |
568 | sh7760fb_free_mem(info); | 568 | sh7760fb_free_mem(info); |
569 | if (par->irq >= 0) | 569 | if (par->irq >= 0) |
570 | free_irq(par->irq, par); | 570 | free_irq(par->irq, &par->vsync); |
571 | iounmap(par->base); | 571 | iounmap(par->base); |
572 | release_mem_region(par->ioarea->start, resource_size(par->ioarea)); | 572 | release_mem_region(par->ioarea->start, resource_size(par->ioarea)); |
573 | framebuffer_release(info); | 573 | framebuffer_release(info); |
diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c index e2e9e3e61b72..8d7810613058 100644 --- a/drivers/video/simplefb.c +++ b/drivers/video/simplefb.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/fb.h> | 24 | #include <linux/fb.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/platform_data/simplefb.h> | ||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | 29 | ||
29 | static struct fb_fix_screeninfo simplefb_fix = { | 30 | static struct fb_fix_screeninfo simplefb_fix = { |
@@ -73,18 +74,7 @@ static struct fb_ops simplefb_ops = { | |||
73 | .fb_imageblit = cfb_imageblit, | 74 | .fb_imageblit = cfb_imageblit, |
74 | }; | 75 | }; |
75 | 76 | ||
76 | struct simplefb_format { | 77 | static struct simplefb_format simplefb_formats[] = SIMPLEFB_FORMATS; |
77 | const char *name; | ||
78 | u32 bits_per_pixel; | ||
79 | struct fb_bitfield red; | ||
80 | struct fb_bitfield green; | ||
81 | struct fb_bitfield blue; | ||
82 | struct fb_bitfield transp; | ||
83 | }; | ||
84 | |||
85 | static struct simplefb_format simplefb_formats[] = { | ||
86 | { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, | ||
87 | }; | ||
88 | 78 | ||
89 | struct simplefb_params { | 79 | struct simplefb_params { |
90 | u32 width; | 80 | u32 width; |
@@ -139,6 +129,33 @@ static int simplefb_parse_dt(struct platform_device *pdev, | |||
139 | return 0; | 129 | return 0; |
140 | } | 130 | } |
141 | 131 | ||
132 | static int simplefb_parse_pd(struct platform_device *pdev, | ||
133 | struct simplefb_params *params) | ||
134 | { | ||
135 | struct simplefb_platform_data *pd = pdev->dev.platform_data; | ||
136 | int i; | ||
137 | |||
138 | params->width = pd->width; | ||
139 | params->height = pd->height; | ||
140 | params->stride = pd->stride; | ||
141 | |||
142 | params->format = NULL; | ||
143 | for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) { | ||
144 | if (strcmp(pd->format, simplefb_formats[i].name)) | ||
145 | continue; | ||
146 | |||
147 | params->format = &simplefb_formats[i]; | ||
148 | break; | ||
149 | } | ||
150 | |||
151 | if (!params->format) { | ||
152 | dev_err(&pdev->dev, "Invalid format value\n"); | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
142 | static int simplefb_probe(struct platform_device *pdev) | 159 | static int simplefb_probe(struct platform_device *pdev) |
143 | { | 160 | { |
144 | int ret; | 161 | int ret; |
@@ -149,7 +166,12 @@ static int simplefb_probe(struct platform_device *pdev) | |||
149 | if (fb_get_options("simplefb", NULL)) | 166 | if (fb_get_options("simplefb", NULL)) |
150 | return -ENODEV; | 167 | return -ENODEV; |
151 | 168 | ||
152 | ret = simplefb_parse_dt(pdev, ¶ms); | 169 | ret = -ENODEV; |
170 | if (pdev->dev.platform_data) | ||
171 | ret = simplefb_parse_pd(pdev, ¶ms); | ||
172 | else if (pdev->dev.of_node) | ||
173 | ret = simplefb_parse_dt(pdev, ¶ms); | ||
174 | |||
153 | if (ret) | 175 | if (ret) |
154 | return ret; | 176 | return ret; |
155 | 177 | ||
@@ -180,8 +202,16 @@ static int simplefb_probe(struct platform_device *pdev) | |||
180 | info->var.blue = params.format->blue; | 202 | info->var.blue = params.format->blue; |
181 | info->var.transp = params.format->transp; | 203 | info->var.transp = params.format->transp; |
182 | 204 | ||
205 | info->apertures = alloc_apertures(1); | ||
206 | if (!info->apertures) { | ||
207 | framebuffer_release(info); | ||
208 | return -ENOMEM; | ||
209 | } | ||
210 | info->apertures->ranges[0].base = info->fix.smem_start; | ||
211 | info->apertures->ranges[0].size = info->fix.smem_len; | ||
212 | |||
183 | info->fbops = &simplefb_ops; | 213 | info->fbops = &simplefb_ops; |
184 | info->flags = FBINFO_DEFAULT; | 214 | info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE; |
185 | info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, | 215 | info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, |
186 | info->fix.smem_len); | 216 | info->fix.smem_len); |
187 | if (!info->screen_base) { | 217 | if (!info->screen_base) { |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 501b3406c6d5..bd83233ec227 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | /* --------------------------------------------------------------------- */ | 30 | /* --------------------------------------------------------------------- */ |
31 | 31 | ||
32 | static struct fb_var_screeninfo vesafb_defined __initdata = { | 32 | static struct fb_var_screeninfo vesafb_defined = { |
33 | .activate = FB_ACTIVATE_NOW, | 33 | .activate = FB_ACTIVATE_NOW, |
34 | .height = -1, | 34 | .height = -1, |
35 | .width = -1, | 35 | .width = -1, |
@@ -40,7 +40,7 @@ static struct fb_var_screeninfo vesafb_defined __initdata = { | |||
40 | .vmode = FB_VMODE_NONINTERLACED, | 40 | .vmode = FB_VMODE_NONINTERLACED, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static struct fb_fix_screeninfo vesafb_fix __initdata = { | 43 | static struct fb_fix_screeninfo vesafb_fix = { |
44 | .id = "VESA VGA", | 44 | .id = "VESA VGA", |
45 | .type = FB_TYPE_PACKED_PIXELS, | 45 | .type = FB_TYPE_PACKED_PIXELS, |
46 | .accel = FB_ACCEL_NONE, | 46 | .accel = FB_ACCEL_NONE, |
@@ -48,8 +48,8 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { | |||
48 | 48 | ||
49 | static int inverse __read_mostly; | 49 | static int inverse __read_mostly; |
50 | static int mtrr __read_mostly; /* disable mtrr */ | 50 | static int mtrr __read_mostly; /* disable mtrr */ |
51 | static int vram_remap __initdata; /* Set amount of memory to be used */ | 51 | static int vram_remap; /* Set amount of memory to be used */ |
52 | static int vram_total __initdata; /* Set total amount of memory */ | 52 | static int vram_total; /* Set total amount of memory */ |
53 | static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ | 53 | static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ |
54 | static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ | 54 | static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ |
55 | static void (*pmi_start)(void) __read_mostly; | 55 | static void (*pmi_start)(void) __read_mostly; |
@@ -192,7 +192,7 @@ static struct fb_ops vesafb_ops = { | |||
192 | .fb_imageblit = cfb_imageblit, | 192 | .fb_imageblit = cfb_imageblit, |
193 | }; | 193 | }; |
194 | 194 | ||
195 | static int __init vesafb_setup(char *options) | 195 | static int vesafb_setup(char *options) |
196 | { | 196 | { |
197 | char *this_opt; | 197 | char *this_opt; |
198 | 198 | ||
@@ -226,13 +226,18 @@ static int __init vesafb_setup(char *options) | |||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
229 | static int __init vesafb_probe(struct platform_device *dev) | 229 | static int vesafb_probe(struct platform_device *dev) |
230 | { | 230 | { |
231 | struct fb_info *info; | 231 | struct fb_info *info; |
232 | int i, err; | 232 | int i, err; |
233 | unsigned int size_vmode; | 233 | unsigned int size_vmode; |
234 | unsigned int size_remap; | 234 | unsigned int size_remap; |
235 | unsigned int size_total; | 235 | unsigned int size_total; |
236 | char *option = NULL; | ||
237 | |||
238 | /* ignore error return of fb_get_options */ | ||
239 | fb_get_options("vesafb", &option); | ||
240 | vesafb_setup(option); | ||
236 | 241 | ||
237 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) | 242 | if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) |
238 | return -ENODEV; | 243 | return -ENODEV; |
@@ -496,40 +501,12 @@ err: | |||
496 | } | 501 | } |
497 | 502 | ||
498 | static struct platform_driver vesafb_driver = { | 503 | static struct platform_driver vesafb_driver = { |
499 | .driver = { | 504 | .driver = { |
500 | .name = "vesafb", | 505 | .name = "vesa-framebuffer", |
506 | .owner = THIS_MODULE, | ||
501 | }, | 507 | }, |
508 | .probe = vesafb_probe, | ||
502 | }; | 509 | }; |
503 | 510 | ||
504 | static struct platform_device *vesafb_device; | 511 | module_platform_driver(vesafb_driver); |
505 | |||
506 | static int __init vesafb_init(void) | ||
507 | { | ||
508 | int ret; | ||
509 | char *option = NULL; | ||
510 | |||
511 | /* ignore error return of fb_get_options */ | ||
512 | fb_get_options("vesafb", &option); | ||
513 | vesafb_setup(option); | ||
514 | |||
515 | vesafb_device = platform_device_alloc("vesafb", 0); | ||
516 | if (!vesafb_device) | ||
517 | return -ENOMEM; | ||
518 | |||
519 | ret = platform_device_add(vesafb_device); | ||
520 | if (!ret) { | ||
521 | ret = platform_driver_probe(&vesafb_driver, vesafb_probe); | ||
522 | if (ret) | ||
523 | platform_device_del(vesafb_device); | ||
524 | } | ||
525 | |||
526 | if (ret) { | ||
527 | platform_device_put(vesafb_device); | ||
528 | vesafb_device = NULL; | ||
529 | } | ||
530 | |||
531 | return ret; | ||
532 | } | ||
533 | module_init(vesafb_init); | ||
534 | |||
535 | MODULE_LICENSE("GPL"); | 512 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 830ded45fd47..2827333703d9 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c | |||
@@ -1265,7 +1265,6 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image | |||
1265 | 1265 | ||
1266 | static void vga16fb_destroy(struct fb_info *info) | 1266 | static void vga16fb_destroy(struct fb_info *info) |
1267 | { | 1267 | { |
1268 | struct platform_device *dev = container_of(info->device, struct platform_device, dev); | ||
1269 | iounmap(info->screen_base); | 1268 | iounmap(info->screen_base); |
1270 | fb_dealloc_cmap(&info->cmap); | 1269 | fb_dealloc_cmap(&info->cmap); |
1271 | /* XXX unshare VGA regions */ | 1270 | /* XXX unshare VGA regions */ |
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index f3d4a69e1e4e..84c664ea8eb9 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
@@ -259,12 +259,12 @@ static int xilinxfb_assign(struct platform_device *pdev, | |||
259 | struct resource *res; | 259 | struct resource *res; |
260 | 260 | ||
261 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 261 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
262 | drvdata->regs_phys = res->start; | 262 | drvdata->regs = devm_ioremap_resource(&pdev->dev, res); |
263 | drvdata->regs = devm_request_and_ioremap(&pdev->dev, res); | 263 | if (IS_ERR(drvdata->regs)) { |
264 | if (!drvdata->regs) { | 264 | rc = PTR_ERR(drvdata->regs); |
265 | rc = -EADDRNOTAVAIL; | ||
266 | goto err_region; | 265 | goto err_region; |
267 | } | 266 | } |
267 | drvdata->regs_phys = res->start; | ||
268 | } | 268 | } |
269 | 269 | ||
270 | /* Allocate the framebuffer memory */ | 270 | /* Allocate the framebuffer memory */ |
@@ -341,8 +341,8 @@ static int xilinxfb_assign(struct platform_device *pdev, | |||
341 | 341 | ||
342 | if (drvdata->flags & BUS_ACCESS_FLAG) { | 342 | if (drvdata->flags & BUS_ACCESS_FLAG) { |
343 | /* Put a banner in the log (for DEBUG) */ | 343 | /* Put a banner in the log (for DEBUG) */ |
344 | dev_dbg(dev, "regs: phys=%x, virt=%p\n", drvdata->regs_phys, | 344 | dev_dbg(dev, "regs: phys=%pa, virt=%p\n", |
345 | drvdata->regs); | 345 | &drvdata->regs_phys, drvdata->regs); |
346 | } | 346 | } |
347 | /* Put a banner in the log (for DEBUG) */ | 347 | /* Put a banner in the log (for DEBUG) */ |
348 | dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n", | 348 | dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n", |