diff options
Diffstat (limited to 'drivers/video')
52 files changed, 975 insertions, 8747 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 bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" depends on FB_NUC900 -config FB_NUC900_DEBUG - bool "NUC900 lcd debug messages" - depends on FB_NUC900 - help - Turn on debugging messages. Note that you can set/unset at run time - through sysfs - config FB_SM501 tristate "Silicon Motion SM501 framebuffer support" depends on FB && MFD_SM501 @@ -2228,15 +2221,17 @@ config FB_SH7760 panels <= 320 pixel horizontal resolution. config FB_DA8XX - tristate "DA8xx/OMAP-L1xx Framebuffer support" - depends on FB && ARCH_DAVINCI_DA8XX + tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support" + depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_CFB_REV_PIXELS_IN_BYTE + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS ---help--- This is the frame buffer device driver for the TI LCD controller - found on DA8xx/OMAP-L1xx SoCs. + found on DA8xx/OMAP-L1xx/AM335x SoCs. If unsure, say N. config FB_VIRTUAL @@ -2457,7 +2452,7 @@ config FB_HYPERV config FB_SIMPLE bool "Simple framebuffer support" - depends on (FB = y) && OF + depends on (FB = y) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -2469,8 +2464,7 @@ config FB_SIMPLE pre-allocated frame buffer surface. Configuration re: surface address, size, and format must be provided - through device tree, or potentially plain old platform data in the - future. + through device tree, or plain old platform data. source "drivers/video/omap/Kconfig" 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) static void atmel_lcdfb_start_clock(struct atmel_lcdfb_info *sinfo) { - clk_enable(sinfo->bus_clk); - clk_enable(sinfo->lcdc_clk); + clk_prepare_enable(sinfo->bus_clk); + clk_prepare_enable(sinfo->lcdc_clk); } static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo) { - clk_disable(sinfo->bus_clk); - clk_disable(sinfo->lcdc_clk); + clk_disable_unprepare(sinfo->bus_clk); + clk_disable_unprepare(sinfo->lcdc_clk); } 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, sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); } -static ssize_t backlight_show_power(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t bl_power_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct backlight_device *bd = to_backlight_device(dev); return sprintf(buf, "%d\n", bd->props.power); } -static ssize_t backlight_store_power(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { int rc; struct backlight_device *bd = to_backlight_device(dev); @@ -136,8 +136,9 @@ static ssize_t backlight_store_power(struct device *dev, return rc; } +static DEVICE_ATTR_RW(bl_power); -static ssize_t backlight_show_brightness(struct device *dev, +static ssize_t brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct backlight_device *bd = to_backlight_device(dev); @@ -145,7 +146,7 @@ static ssize_t backlight_show_brightness(struct device *dev, return sprintf(buf, "%d\n", bd->props.brightness); } -static ssize_t backlight_store_brightness(struct device *dev, +static ssize_t brightness_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc; @@ -175,24 +176,27 @@ static ssize_t backlight_store_brightness(struct device *dev, return rc; } +static DEVICE_ATTR_RW(brightness); -static ssize_t backlight_show_type(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t type_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct backlight_device *bd = to_backlight_device(dev); return sprintf(buf, "%s\n", backlight_types[bd->props.type]); } +static DEVICE_ATTR_RO(type); -static ssize_t backlight_show_max_brightness(struct device *dev, +static ssize_t max_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct backlight_device *bd = to_backlight_device(dev); return sprintf(buf, "%d\n", bd->props.max_brightness); } +static DEVICE_ATTR_RO(max_brightness); -static ssize_t backlight_show_actual_brightness(struct device *dev, +static ssize_t actual_brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { int rc = -ENXIO; @@ -205,6 +209,7 @@ static ssize_t backlight_show_actual_brightness(struct device *dev, return rc; } +static DEVICE_ATTR_RO(actual_brightness); static struct class *backlight_class; @@ -247,16 +252,15 @@ static void bl_device_release(struct device *dev) kfree(bd); } -static struct device_attribute bl_device_attributes[] = { - __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), - __ATTR(brightness, 0644, backlight_show_brightness, - backlight_store_brightness), - __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, - NULL), - __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), - __ATTR(type, 0444, backlight_show_type, NULL), - __ATTR_NULL, +static struct attribute *bl_device_attrs[] = { + &dev_attr_bl_power.attr, + &dev_attr_brightness.attr, + &dev_attr_actual_brightness.attr, + &dev_attr_max_brightness.attr, + &dev_attr_type.attr, + NULL, }; +ATTRIBUTE_GROUPS(bl_device); /** * backlight_force_update - tell the backlight subsystem that hardware state @@ -493,7 +497,7 @@ static int __init backlight_class_init(void) return PTR_ERR(backlight_class); } - backlight_class->dev_attrs = bl_device_attributes; + backlight_class->dev_groups = bl_device_groups; backlight_class->pm = &backlight_class_dev_pm_ops; return 0; } 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 @@ #define HX8357_SET_POWER_NORMAL 0xd2 #define HX8357_SET_PANEL_RELATED 0xe9 +#define HX8369_SET_DISPLAY_BRIGHTNESS 0x51 +#define HX8369_WRITE_CABC_DISPLAY_VALUE 0x53 +#define HX8369_WRITE_CABC_BRIGHT_CTRL 0x55 +#define HX8369_WRITE_CABC_MIN_BRIGHTNESS 0x5e +#define HX8369_SET_POWER 0xb1 +#define HX8369_SET_DISPLAY_MODE 0xb2 +#define HX8369_SET_DISPLAY_WAVEFORM_CYC 0xb4 +#define HX8369_SET_VCOM 0xb6 +#define HX8369_SET_EXTENSION_COMMAND 0xb9 +#define HX8369_SET_GIP 0xd5 +#define HX8369_SET_GAMMA_CURVE_RELATED 0xe0 + struct hx8357_data { unsigned im_pins[HX8357_NUM_IM_PINS]; unsigned reset; struct spi_device *spi; int state; + bool use_im_pins; }; static u8 hx8357_seq_power[] = { @@ -143,6 +156,61 @@ static u8 hx8357_seq_display_mode[] = { HX8357_SET_DISPLAY_MODE_RGB_INTERFACE, }; +static u8 hx8369_seq_write_CABC_min_brightness[] = { + HX8369_WRITE_CABC_MIN_BRIGHTNESS, 0x00, +}; + +static u8 hx8369_seq_write_CABC_control[] = { + HX8369_WRITE_CABC_DISPLAY_VALUE, 0x24, +}; + +static u8 hx8369_seq_set_display_brightness[] = { + HX8369_SET_DISPLAY_BRIGHTNESS, 0xFF, +}; + +static u8 hx8369_seq_write_CABC_control_setting[] = { + HX8369_WRITE_CABC_BRIGHT_CTRL, 0x02, +}; + +static u8 hx8369_seq_extension_command[] = { + HX8369_SET_EXTENSION_COMMAND, 0xff, 0x83, 0x69, +}; + +static u8 hx8369_seq_display_related[] = { + HX8369_SET_DISPLAY_MODE, 0x00, 0x2b, 0x03, 0x03, 0x70, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x01, +}; + +static u8 hx8369_seq_panel_waveform_cycle[] = { + HX8369_SET_DISPLAY_WAVEFORM_CYC, 0x0a, 0x1d, 0x80, 0x06, 0x02, +}; + +static u8 hx8369_seq_set_address_mode[] = { + HX8357_SET_ADDRESS_MODE, 0x00, +}; + +static u8 hx8369_seq_vcom[] = { + HX8369_SET_VCOM, 0x3e, 0x3e, +}; + +static u8 hx8369_seq_gip[] = { + HX8369_SET_GIP, 0x00, 0x01, 0x03, 0x25, 0x01, 0x02, 0x28, 0x70, + 0x11, 0x13, 0x00, 0x00, 0x40, 0x26, 0x51, 0x37, 0x00, 0x00, 0x71, + 0x35, 0x60, 0x24, 0x07, 0x0f, 0x04, 0x04, +}; + +static u8 hx8369_seq_power[] = { + HX8369_SET_POWER, 0x01, 0x00, 0x34, 0x03, 0x00, 0x11, 0x11, 0x32, + 0x2f, 0x3f, 0x3f, 0x01, 0x3a, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, +}; + +static u8 hx8369_seq_gamma_curve_related[] = { + HX8369_SET_GAMMA_CURVE_RELATED, 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d, + 0x2e, 0x4a, 0x08, 0x0e, 0x0f, 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e, + 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d, 0x2e, 0x4a, 0x08, 0x0e, 0x0f, + 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e, +}; + static int hx8357_spi_write_then_read(struct lcd_device *lcdev, u8 *txbuf, u16 txlen, u8 *rxbuf, u16 rxlen) @@ -219,6 +287,10 @@ static int hx8357_enter_standby(struct lcd_device *lcdev) if (ret < 0) return ret; + /* + * The controller needs 120ms when entering in sleep mode before we can + * send the command to go off sleep mode + */ msleep(120); return 0; @@ -232,6 +304,10 @@ static int hx8357_exit_standby(struct lcd_device *lcdev) if (ret < 0) return ret; + /* + * The controller needs 120ms when exiting from sleep mode before we + * can send the command to enter in sleep mode + */ msleep(120); ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); @@ -241,18 +317,9 @@ static int hx8357_exit_standby(struct lcd_device *lcdev) return 0; } -static int hx8357_lcd_init(struct lcd_device *lcdev) +static void hx8357_lcd_reset(struct lcd_device *lcdev) { struct hx8357_data *lcd = lcd_get_data(lcdev); - int ret; - - /* - * Set the interface selection pins to SPI mode, with three - * wires - */ - gpio_set_value_cansleep(lcd->im_pins[0], 1); - gpio_set_value_cansleep(lcd->im_pins[1], 0); - gpio_set_value_cansleep(lcd->im_pins[2], 1); /* Reset the screen */ gpio_set_value(lcd->reset, 1); @@ -260,7 +327,25 @@ static int hx8357_lcd_init(struct lcd_device *lcdev) gpio_set_value(lcd->reset, 0); usleep_range(10000, 12000); gpio_set_value(lcd->reset, 1); + + /* The controller needs 120ms to recover from reset */ msleep(120); +} + +static int hx8357_lcd_init(struct lcd_device *lcdev) +{ + struct hx8357_data *lcd = lcd_get_data(lcdev); + int ret; + + /* + * Set the interface selection pins to SPI mode, with three + * wires + */ + if (lcd->use_im_pins) { + gpio_set_value_cansleep(lcd->im_pins[0], 1); + gpio_set_value_cansleep(lcd->im_pins[1], 0); + gpio_set_value_cansleep(lcd->im_pins[2], 1); + } ret = hx8357_spi_write_array(lcdev, hx8357_seq_power, ARRAY_SIZE(hx8357_seq_power)); @@ -341,6 +426,9 @@ static int hx8357_lcd_init(struct lcd_device *lcdev) if (ret < 0) return ret; + /* + * The controller needs 120ms to fully recover from exiting sleep mode + */ msleep(120); ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); @@ -356,6 +444,96 @@ static int hx8357_lcd_init(struct lcd_device *lcdev) return 0; } +static int hx8369_lcd_init(struct lcd_device *lcdev) +{ + int ret; + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_extension_command, + ARRAY_SIZE(hx8369_seq_extension_command)); + if (ret < 0) + return ret; + usleep_range(10000, 12000); + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_display_related, + ARRAY_SIZE(hx8369_seq_display_related)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_panel_waveform_cycle, + ARRAY_SIZE(hx8369_seq_panel_waveform_cycle)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_address_mode, + ARRAY_SIZE(hx8369_seq_set_address_mode)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_vcom, + ARRAY_SIZE(hx8369_seq_vcom)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_gip, + ARRAY_SIZE(hx8369_seq_gip)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_power, + ARRAY_SIZE(hx8369_seq_power)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE); + if (ret < 0) + return ret; + + /* + * The controller needs 120ms to fully recover from exiting sleep mode + */ + msleep(120); + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_gamma_curve_related, + ARRAY_SIZE(hx8369_seq_gamma_curve_related)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE); + if (ret < 0) + return ret; + usleep_range(1000, 1200); + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_write_CABC_control, + ARRAY_SIZE(hx8369_seq_write_CABC_control)); + if (ret < 0) + return ret; + usleep_range(10000, 12000); + + ret = hx8357_spi_write_array(lcdev, + hx8369_seq_write_CABC_control_setting, + ARRAY_SIZE(hx8369_seq_write_CABC_control_setting)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_array(lcdev, + hx8369_seq_write_CABC_min_brightness, + ARRAY_SIZE(hx8369_seq_write_CABC_min_brightness)); + if (ret < 0) + return ret; + usleep_range(10000, 12000); + + ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_display_brightness, + ARRAY_SIZE(hx8369_seq_set_display_brightness)); + if (ret < 0) + return ret; + + ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); + if (ret < 0) + return ret; + + return 0; +} + #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) static int hx8357_set_power(struct lcd_device *lcdev, int power) @@ -388,10 +566,24 @@ static struct lcd_ops hx8357_ops = { .get_power = hx8357_get_power, }; +static const struct of_device_id hx8357_dt_ids[] = { + { + .compatible = "himax,hx8357", + .data = hx8357_lcd_init, + }, + { + .compatible = "himax,hx8369", + .data = hx8369_lcd_init, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, hx8357_dt_ids); + static int hx8357_probe(struct spi_device *spi) { struct lcd_device *lcdev; struct hx8357_data *lcd; + const struct of_device_id *match; int i, ret; lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); @@ -408,6 +600,10 @@ static int hx8357_probe(struct spi_device *spi) lcd->spi = spi; + match = of_match_device(hx8357_dt_ids, &spi->dev); + if (!match || !match->data) + return -EINVAL; + lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0); if (!gpio_is_valid(lcd->reset)) { dev_err(&spi->dev, "Missing dt property: gpios-reset\n"); @@ -424,25 +620,32 @@ static int hx8357_probe(struct spi_device *spi) return -EINVAL; } - for (i = 0; i < HX8357_NUM_IM_PINS; i++) { - lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, - "im-gpios", i); - if (lcd->im_pins[i] == -EPROBE_DEFER) { - dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n"); - return -EPROBE_DEFER; - } - if (!gpio_is_valid(lcd->im_pins[i])) { - dev_err(&spi->dev, "Missing dt property: im-gpios\n"); - return -EINVAL; - } - - ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i], - GPIOF_OUT_INIT_LOW, "im_pins"); - if (ret) { - dev_err(&spi->dev, "failed to request gpio %d: %d\n", - lcd->im_pins[i], ret); - return -EINVAL; + if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) { + lcd->use_im_pins = 1; + + for (i = 0; i < HX8357_NUM_IM_PINS; i++) { + lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, + "im-gpios", i); + if (lcd->im_pins[i] == -EPROBE_DEFER) { + dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n"); + return -EPROBE_DEFER; + } + if (!gpio_is_valid(lcd->im_pins[i])) { + dev_err(&spi->dev, "Missing dt property: im-gpios\n"); + return -EINVAL; + } + + ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i], + GPIOF_OUT_INIT_LOW, + "im_pins"); + if (ret) { + dev_err(&spi->dev, "failed to request gpio %d: %d\n", + lcd->im_pins[i], ret); + return -EINVAL; + } } + } else { + lcd->use_im_pins = 0; } lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops); @@ -452,7 +655,9 @@ static int hx8357_probe(struct spi_device *spi) } spi_set_drvdata(spi, lcdev); - ret = hx8357_lcd_init(lcdev); + hx8357_lcd_reset(lcdev); + + ret = ((int (*)(struct lcd_device *))match->data)(lcdev); if (ret) { dev_err(&spi->dev, "Couldn't initialize panel\n"); goto init_error; @@ -475,12 +680,6 @@ static int hx8357_remove(struct spi_device *spi) return 0; } -static const struct of_device_id hx8357_dt_ids[] = { - { .compatible = "himax,hx8357" }, - {}, -}; -MODULE_DEVICE_TABLE(of, hx8357_dt_ids); - static struct spi_driver hx8357_driver = { .probe = hx8357_probe, .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) } #endif /* CONFIG_FB */ -static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr, +static ssize_t lcd_power_show(struct device *dev, struct device_attribute *attr, char *buf) { int rc; @@ -105,7 +105,7 @@ static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr, return rc; } -static ssize_t lcd_store_power(struct device *dev, +static ssize_t lcd_power_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc; @@ -128,8 +128,9 @@ static ssize_t lcd_store_power(struct device *dev, return rc; } +static DEVICE_ATTR_RW(lcd_power); -static ssize_t lcd_show_contrast(struct device *dev, +static ssize_t contrast_show(struct device *dev, struct device_attribute *attr, char *buf) { int rc = -ENXIO; @@ -143,7 +144,7 @@ static ssize_t lcd_show_contrast(struct device *dev, return rc; } -static ssize_t lcd_store_contrast(struct device *dev, +static ssize_t contrast_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc; @@ -166,14 +167,16 @@ static ssize_t lcd_store_contrast(struct device *dev, return rc; } +static DEVICE_ATTR_RW(contrast); -static ssize_t lcd_show_max_contrast(struct device *dev, +static ssize_t max_contrast_show(struct device *dev, struct device_attribute *attr, char *buf) { struct lcd_device *ld = to_lcd_device(dev); return sprintf(buf, "%d\n", ld->props.max_contrast); } +static DEVICE_ATTR_RO(max_contrast); static struct class *lcd_class; @@ -183,12 +186,13 @@ static void lcd_device_release(struct device *dev) kfree(ld); } -static struct device_attribute lcd_device_attributes[] = { - __ATTR(lcd_power, 0644, lcd_show_power, lcd_store_power), - __ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast), - __ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), - __ATTR_NULL, +static struct attribute *lcd_device_attrs[] = { + &dev_attr_lcd_power.attr, + &dev_attr_contrast.attr, + &dev_attr_max_contrast.attr, + NULL, }; +ATTRIBUTE_GROUPS(lcd_device); /** * lcd_device_register - register a new object of lcd_device class. @@ -344,7 +348,7 @@ static int __init lcd_class_init(void) return PTR_ERR(lcd_class); } - lcd_class->dev_attrs = lcd_device_attributes; + lcd_class->dev_groups = lcd_device_groups; return 0; } 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) { struct lp855x *lp = bl_get_data(bl); - if (bl->props.state & BL_CORE_SUSPENDED) + if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) bl->props.brightness = 0; if (lp->mode == PWM_BASED) { 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 config FRAMEBUFFER_CONSOLE tristate "Framebuffer Console support" - depends on FB + depends on FB && !UML + select VT_HW_CONSOLE_BINDING select CRC32 select FONT_SUPPORT 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 @@ #define WSI_TIMEOUT 50 #define PALETTE_SIZE 256 -#define LEFT_MARGIN 64 -#define RIGHT_MARGIN 64 -#define UPPER_MARGIN 32 -#define LOWER_MARGIN 32 + +#define CLK_MIN_DIV 2 +#define CLK_MAX_DIV 255 static void __iomem *da8xx_fb_reg_base; -static struct resource *lcdc_regs; static unsigned int lcd_revision; static irq_handler_t lcdc_irq_handler; static wait_queue_head_t frame_done_wq; static int frame_done_flag; -static inline unsigned int lcdc_read(unsigned int addr) +static unsigned int lcdc_read(unsigned int addr) { return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr)); } -static inline void lcdc_write(unsigned int val, unsigned int addr) +static void lcdc_write(unsigned int val, unsigned int addr) { __raw_writel(val, da8xx_fb_reg_base + (addr)); } struct da8xx_fb_par { + struct device *dev; resource_size_t p_palette_base; unsigned char *v_palette_base; dma_addr_t vram_phys; @@ -164,7 +163,6 @@ struct da8xx_fb_par { struct clk *lcdc_clk; int irq; unsigned int palette_sz; - unsigned int pxl_clk; int blank; wait_queue_head_t vsync_wait; int vsync_flag; @@ -178,29 +176,15 @@ struct da8xx_fb_par { unsigned int which_dma_channel_done; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; - unsigned int lcd_fck_rate; #endif + unsigned int lcdc_clk_rate; void (*panel_power_ctrl)(int); u32 pseudo_palette[16]; + struct fb_videomode mode; + struct lcd_ctrl_config cfg; }; -/* Variable Screen Information */ -static struct fb_var_screeninfo da8xx_fb_var = { - .xoffset = 0, - .yoffset = 0, - .transp = {0, 0, 0}, - .nonstd = 0, - .activate = 0, - .height = -1, - .width = -1, - .accel_flags = 0, - .left_margin = LEFT_MARGIN, - .right_margin = RIGHT_MARGIN, - .upper_margin = UPPER_MARGIN, - .lower_margin = LOWER_MARGIN, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED -}; +static struct fb_var_screeninfo da8xx_fb_var; static struct fb_fix_screeninfo da8xx_fb_fix = { .id = "DA8xx FB Drv", @@ -219,7 +203,7 @@ static struct fb_videomode known_lcd_panels[] = { .name = "Sharp_LCD035Q3DG01", .xres = 320, .yres = 240, - .pixclock = 4608000, + .pixclock = KHZ2PICOS(4607), .left_margin = 6, .right_margin = 8, .upper_margin = 2, @@ -234,7 +218,7 @@ static struct fb_videomode known_lcd_panels[] = { .name = "Sharp_LK043T1DG01", .xres = 480, .yres = 272, - .pixclock = 7833600, + .pixclock = KHZ2PICOS(7833), .left_margin = 2, .right_margin = 2, .upper_margin = 2, @@ -249,7 +233,7 @@ static struct fb_videomode known_lcd_panels[] = { .name = "SP10Q010", .xres = 320, .yres = 240, - .pixclock = 7833600, + .pixclock = KHZ2PICOS(7833), .left_margin = 10, .right_margin = 10, .upper_margin = 10, @@ -261,8 +245,13 @@ static struct fb_videomode known_lcd_panels[] = { }, }; +static bool da8xx_fb_is_raster_enabled(void) +{ + return !!(lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE); +} + /* Enable the Raster Engine of the LCD Controller */ -static inline void lcd_enable_raster(void) +static void lcd_enable_raster(void) { u32 reg; @@ -284,7 +273,7 @@ static inline void lcd_enable_raster(void) } /* Disable the Raster Engine of the LCD Controller */ -static inline void lcd_disable_raster(bool wait_for_frame_done) +static void lcd_disable_raster(enum da8xx_frame_complete wait_for_frame_done) { u32 reg; int ret; @@ -296,7 +285,8 @@ static inline void lcd_disable_raster(bool wait_for_frame_done) /* return if already disabled */ return; - if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) { + if ((wait_for_frame_done == DA8XX_FRAME_WAIT) && + (lcd_revision == LCD_VERSION_2)) { frame_done_flag = 0; ret = wait_event_interruptible_timeout(frame_done_wq, frame_done_flag != 0, @@ -331,7 +321,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par) reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) | LCD_V2_END_OF_FRAME0_INT_ENA | LCD_V2_END_OF_FRAME1_INT_ENA | - LCD_FRAME_DONE; + LCD_FRAME_DONE | LCD_SYNC_LOST; lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG); } reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; @@ -417,10 +407,25 @@ static void lcd_cfg_horizontal_sync(int back_porch, int pulse_width, u32 reg; reg = lcdc_read(LCD_RASTER_TIMING_0_REG) & 0xf; - reg |= ((back_porch & 0xff) << 24) - | ((front_porch & 0xff) << 16) - | ((pulse_width & 0x3f) << 10); + reg |= (((back_porch-1) & 0xff) << 24) + | (((front_porch-1) & 0xff) << 16) + | (((pulse_width-1) & 0x3f) << 10); lcdc_write(reg, LCD_RASTER_TIMING_0_REG); + + /* + * LCDC Version 2 adds some extra bits that increase the allowable + * size of the horizontal timing registers. + * remember that the registers use 0 to represent 1 so all values + * that get set into register need to be decremented by 1 + */ + if (lcd_revision == LCD_VERSION_2) { + /* Mask off the bits we want to change */ + reg = lcdc_read(LCD_RASTER_TIMING_2_REG) & ~0x780000ff; + reg |= ((front_porch-1) & 0x300) >> 8; + reg |= ((back_porch-1) & 0x300) >> 4; + reg |= ((pulse_width-1) & 0x3c0) << 21; + lcdc_write(reg, LCD_RASTER_TIMING_2_REG); + } } 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, reg = lcdc_read(LCD_RASTER_TIMING_1_REG) & 0x3ff; reg |= ((back_porch & 0xff) << 24) | ((front_porch & 0xff) << 16) - | ((pulse_width & 0x3f) << 10); + | (((pulse_width-1) & 0x3f) << 10); lcdc_write(reg, LCD_RASTER_TIMING_1_REG); } @@ -488,12 +493,12 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg, else reg &= ~LCD_SYNC_EDGE; - if (panel->sync & FB_SYNC_HOR_HIGH_ACT) + if ((panel->sync & FB_SYNC_HOR_HIGH_ACT) == 0) reg |= LCD_INVERT_LINE_CLOCK; else reg &= ~LCD_INVERT_LINE_CLOCK; - if (panel->sync & FB_SYNC_VERT_HIGH_ACT) + if ((panel->sync & FB_SYNC_VERT_HIGH_ACT) == 0) reg |= LCD_INVERT_FRAME_CLOCK; else reg &= ~LCD_INVERT_FRAME_CLOCK; @@ -565,10 +570,11 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, break; case 24: reg |= LCD_V2_TFT_24BPP_MODE; + break; case 32: + reg |= LCD_V2_TFT_24BPP_MODE; reg |= LCD_V2_TFT_24BPP_UNPACK; break; - case 8: par->palette_sz = 256 * 2; break; @@ -681,11 +687,8 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, } #undef CNVT_TOHW -static void lcd_reset(struct da8xx_fb_par *par) +static void da8xx_fb_lcd_reset(void) { - /* Disable the Raster if previously Enabled */ - lcd_disable_raster(false); - /* DMA has to be disabled */ lcdc_write(0, LCD_DMA_CTRL_REG); lcdc_write(0, LCD_RASTER_CTRL_REG); @@ -698,21 +701,76 @@ static void lcd_reset(struct da8xx_fb_par *par) } } -static void lcd_calc_clk_divider(struct da8xx_fb_par *par) +static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par, + unsigned lcdc_clk_div, + unsigned lcdc_clk_rate) { - unsigned int lcd_clk, div; + int ret; - lcd_clk = clk_get_rate(par->lcdc_clk); - div = lcd_clk / par->pxl_clk; + if (par->lcdc_clk_rate != lcdc_clk_rate) { + ret = clk_set_rate(par->lcdc_clk, lcdc_clk_rate); + if (IS_ERR_VALUE(ret)) { + dev_err(par->dev, + "unable to set clock rate at %u\n", + lcdc_clk_rate); + return ret; + } + par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); + } /* Configure the LCD clock divisor. */ - lcdc_write(LCD_CLK_DIVISOR(div) | + lcdc_write(LCD_CLK_DIVISOR(lcdc_clk_div) | (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); if (lcd_revision == LCD_VERSION_2) lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN | LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG); + return 0; +} + +static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par, + unsigned pixclock, + unsigned *lcdc_clk_rate) +{ + unsigned lcdc_clk_div; + + pixclock = PICOS2KHZ(pixclock) * 1000; + + *lcdc_clk_rate = par->lcdc_clk_rate; + + if (pixclock < (*lcdc_clk_rate / CLK_MAX_DIV)) { + *lcdc_clk_rate = clk_round_rate(par->lcdc_clk, + pixclock * CLK_MAX_DIV); + lcdc_clk_div = CLK_MAX_DIV; + } else if (pixclock > (*lcdc_clk_rate / CLK_MIN_DIV)) { + *lcdc_clk_rate = clk_round_rate(par->lcdc_clk, + pixclock * CLK_MIN_DIV); + lcdc_clk_div = CLK_MIN_DIV; + } else { + lcdc_clk_div = *lcdc_clk_rate / pixclock; + } + + return lcdc_clk_div; +} + +static int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par, + struct fb_videomode *mode) +{ + unsigned lcdc_clk_rate; + unsigned lcdc_clk_div = da8xx_fb_calc_clk_divider(par, mode->pixclock, + &lcdc_clk_rate); + + return da8xx_fb_config_clk_divider(par, lcdc_clk_div, lcdc_clk_rate); +} + +static unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par, + unsigned pixclock) +{ + unsigned lcdc_clk_div, lcdc_clk_rate; + + lcdc_clk_div = da8xx_fb_calc_clk_divider(par, pixclock, &lcdc_clk_rate); + return KHZ2PICOS(lcdc_clk_rate / (1000 * lcdc_clk_div)); } 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, u32 bpp; int ret = 0; - lcd_reset(par); - - /* Calculate the divider */ - lcd_calc_clk_divider(par); + ret = da8xx_fb_calc_config_clk_divider(par, panel); + if (IS_ERR_VALUE(ret)) { + dev_err(par->dev, "unable to configure clock\n"); + return ret; + } if (panel->sync & FB_SYNC_CLK_INVERT) 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, return ret; /* Configure the vertical and horizontal sync properties. */ - lcd_cfg_vertical_sync(panel->lower_margin, panel->vsync_len, - panel->upper_margin); - lcd_cfg_horizontal_sync(panel->right_margin, panel->hsync_len, - panel->left_margin); + lcd_cfg_vertical_sync(panel->upper_margin, panel->vsync_len, + panel->lower_margin); + lcd_cfg_horizontal_sync(panel->left_margin, panel->hsync_len, + panel->right_margin); /* Configure for disply */ ret = lcd_cfg_display(cfg, panel); @@ -773,7 +832,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) u32 stat = lcdc_read(LCD_MASKED_STAT_REG); if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { - lcd_disable_raster(false); + lcd_disable_raster(DA8XX_FRAME_NOWAIT); lcdc_write(stat, LCD_MASKED_STAT_REG); lcd_enable_raster(); } else if (stat & LCD_PL_LOAD_DONE) { @@ -783,7 +842,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg) * interrupt via the following write to the status register. If * this is done after then one gets multiple PL done interrupts. */ - lcd_disable_raster(false); + lcd_disable_raster(DA8XX_FRAME_NOWAIT); lcdc_write(stat, LCD_MASKED_STAT_REG); @@ -836,7 +895,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) u32 reg_ras; if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { - lcd_disable_raster(false); + lcd_disable_raster(DA8XX_FRAME_NOWAIT); lcdc_write(stat, LCD_STAT_REG); lcd_enable_raster(); } else if (stat & LCD_PL_LOAD_DONE) { @@ -846,7 +905,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg) * interrupt via the following write to the status register. If * this is done after then one gets multiple PL done interrupts. */ - lcd_disable_raster(false); + lcd_disable_raster(DA8XX_FRAME_NOWAIT); lcdc_write(stat, LCD_STAT_REG); @@ -888,6 +947,9 @@ static int fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { int err = 0; + struct da8xx_fb_par *par = info->par; + int bpp = var->bits_per_pixel >> 3; + unsigned long line_size = var->xres_virtual * bpp; if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1) return -EINVAL; @@ -955,6 +1017,23 @@ static int fb_check_var(struct fb_var_screeninfo *var, var->green.msb_right = 0; var->blue.msb_right = 0; var->transp.msb_right = 0; + + if (line_size * var->yres_virtual > par->vram_size) + var->yres_virtual = par->vram_size / line_size; + + if (var->yres > var->yres_virtual) + var->yres = var->yres_virtual; + + if (var->xres > var->xres_virtual) + var->xres = var->xres_virtual; + + if (var->xres + var->xoffset > var->xres_virtual) + var->xoffset = var->xres_virtual - var->xres; + if (var->yres + var->yoffset > var->yres_virtual) + var->yoffset = var->yres_virtual - var->yres; + + var->pixclock = da8xx_fb_round_clk(par, var->pixclock); + return err; } @@ -966,10 +1045,10 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, par = container_of(nb, struct da8xx_fb_par, freq_transition); if (val == CPUFREQ_POSTCHANGE) { - if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { - par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); - lcd_disable_raster(true); - lcd_calc_clk_divider(par); + if (par->lcdc_clk_rate != clk_get_rate(par->lcdc_clk)) { + par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); + lcd_disable_raster(DA8XX_FRAME_WAIT); + da8xx_fb_calc_config_clk_divider(par, &par->mode); if (par->blank == FB_BLANK_UNBLANK) lcd_enable_raster(); } @@ -978,7 +1057,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, return 0; } -static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) +static int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) { par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition; @@ -986,7 +1065,7 @@ static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) CPUFREQ_TRANSITION_NOTIFIER); } -static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par) +static void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par) { cpufreq_unregister_notifier(&par->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); @@ -1006,7 +1085,7 @@ static int fb_remove(struct platform_device *dev) if (par->panel_power_ctrl) par->panel_power_ctrl(0); - lcd_disable_raster(true); + lcd_disable_raster(DA8XX_FRAME_WAIT); lcdc_write(0, LCD_RASTER_CTRL_REG); /* disable DMA */ @@ -1018,12 +1097,9 @@ static int fb_remove(struct platform_device *dev) par->p_palette_base); dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys); - free_irq(par->irq, par); pm_runtime_put_sync(&dev->dev); pm_runtime_disable(&dev->dev); framebuffer_release(info); - iounmap(da8xx_fb_reg_base); - release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); } return 0; @@ -1122,7 +1198,7 @@ static int cfb_blank(int blank, struct fb_info *info) if (par->panel_power_ctrl) par->panel_power_ctrl(0); - lcd_disable_raster(true); + lcd_disable_raster(DA8XX_FRAME_WAIT); break; default: ret = -EINVAL; @@ -1183,9 +1259,50 @@ static int da8xx_pan_display(struct fb_var_screeninfo *var, return ret; } +static int da8xxfb_set_par(struct fb_info *info) +{ + struct da8xx_fb_par *par = info->par; + int ret; + bool raster = da8xx_fb_is_raster_enabled(); + + if (raster) + lcd_disable_raster(DA8XX_FRAME_WAIT); + + fb_var_to_videomode(&par->mode, &info->var); + + par->cfg.bpp = info->var.bits_per_pixel; + + info->fix.visual = (par->cfg.bpp <= 8) ? + FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + info->fix.line_length = (par->mode.xres * par->cfg.bpp) / 8; + + ret = lcd_init(par, &par->cfg, &par->mode); + if (ret < 0) { + dev_err(par->dev, "lcd init failed\n"); + return ret; + } + + par->dma_start = info->fix.smem_start + + info->var.yoffset * info->fix.line_length + + info->var.xoffset * info->var.bits_per_pixel / 8; + par->dma_end = par->dma_start + + info->var.yres * info->fix.line_length - 1; + + lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + lcdc_write(par->dma_start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + lcdc_write(par->dma_end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + + if (raster) + lcd_enable_raster(); + + return 0; +} + static struct fb_ops da8xx_fb_ops = { .owner = THIS_MODULE, .fb_check_var = fb_check_var, + .fb_set_par = da8xxfb_set_par, .fb_setcolreg = fb_setcolreg, .fb_pan_display = da8xx_pan_display, .fb_ioctl = fb_ioctl, @@ -1195,33 +1312,38 @@ static struct fb_ops da8xx_fb_ops = { .fb_blank = cfb_blank, }; -/* Calculate and return pixel clock period in pico seconds */ -static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par) +static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev) { - unsigned int lcd_clk, div; - unsigned int configured_pix_clk; - unsigned long long pix_clk_period_picosec = 1000000000000ULL; + struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; + struct fb_videomode *lcdc_info; + int i; - lcd_clk = clk_get_rate(par->lcdc_clk); - div = lcd_clk / par->pxl_clk; - configured_pix_clk = (lcd_clk / div); + for (i = 0, lcdc_info = known_lcd_panels; + i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) { + if (strcmp(fb_pdata->type, lcdc_info->name) == 0) + break; + } - do_div(pix_clk_period_picosec, configured_pix_clk); + if (i == ARRAY_SIZE(known_lcd_panels)) { + dev_err(&dev->dev, "no panel found\n"); + return NULL; + } + dev_info(&dev->dev, "found %s panel\n", lcdc_info->name); - return pix_clk_period_picosec; + return lcdc_info; } static int fb_probe(struct platform_device *device) { struct da8xx_lcdc_platform_data *fb_pdata = device->dev.platform_data; + static struct resource *lcdc_regs; struct lcd_ctrl_config *lcd_cfg; struct fb_videomode *lcdc_info; struct fb_info *da8xx_fb_info; - struct clk *fb_clk = NULL; struct da8xx_fb_par *par; - resource_size_t len; - int ret, i; + struct clk *tmp_lcdc_clk; + int ret; unsigned long ulcm; if (fb_pdata == NULL) { @@ -1229,30 +1351,19 @@ static int fb_probe(struct platform_device *device) return -ENOENT; } - lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0); - if (!lcdc_regs) { - dev_err(&device->dev, - "Can not get memory resource for LCD controller\n"); - return -ENOENT; - } - - len = resource_size(lcdc_regs); + lcdc_info = da8xx_fb_get_videomode(device); + if (lcdc_info == NULL) + return -ENODEV; - lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name); - if (!lcdc_regs) - return -EBUSY; - - da8xx_fb_reg_base = ioremap(lcdc_regs->start, len); - if (!da8xx_fb_reg_base) { - ret = -EBUSY; - goto err_request_mem; - } + lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0); + da8xx_fb_reg_base = devm_ioremap_resource(&device->dev, lcdc_regs); + if (IS_ERR(da8xx_fb_reg_base)) + return PTR_ERR(da8xx_fb_reg_base); - fb_clk = clk_get(&device->dev, "fck"); - if (IS_ERR(fb_clk)) { + tmp_lcdc_clk = devm_clk_get(&device->dev, "fck"); + if (IS_ERR(tmp_lcdc_clk)) { dev_err(&device->dev, "Can not get device clock\n"); - ret = -ENODEV; - goto err_ioremap; + return PTR_ERR(tmp_lcdc_clk); } pm_runtime_enable(&device->dev); @@ -1275,22 +1386,12 @@ static int fb_probe(struct platform_device *device) break; } - for (i = 0, lcdc_info = known_lcd_panels; - i < ARRAY_SIZE(known_lcd_panels); - i++, lcdc_info++) { - if (strcmp(fb_pdata->type, lcdc_info->name) == 0) - break; - } + lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; - if (i == ARRAY_SIZE(known_lcd_panels)) { - dev_err(&device->dev, "GLCD: No valid panel found\n"); - ret = -ENODEV; + if (!lcd_cfg) { + ret = -EINVAL; goto err_pm_runtime_disable; - } else - dev_info(&device->dev, "GLCD: Found %s panel\n", - fb_pdata->type); - - lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data; + } da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par), &device->dev); @@ -1301,21 +1402,18 @@ static int fb_probe(struct platform_device *device) } par = da8xx_fb_info->par; - par->lcdc_clk = fb_clk; -#ifdef CONFIG_CPU_FREQ - par->lcd_fck_rate = clk_get_rate(fb_clk); -#endif - par->pxl_clk = lcdc_info->pixclock; + par->dev = &device->dev; + par->lcdc_clk = tmp_lcdc_clk; + par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk); if (fb_pdata->panel_power_ctrl) { par->panel_power_ctrl = fb_pdata->panel_power_ctrl; par->panel_power_ctrl(1); } - if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { - dev_err(&device->dev, "lcd_init failed\n"); - ret = -EFAULT; - goto err_release_fb; - } + fb_videomode_to_var(&da8xx_fb_var, lcdc_info); + par->cfg = *lcd_cfg; + + da8xx_fb_lcd_reset(); /* allocate frame buffer */ par->vram_size = lcdc_info->xres * lcdc_info->yres * lcd_cfg->bpp; @@ -1363,27 +1461,10 @@ static int fb_probe(struct platform_device *device) goto err_release_pl_mem; } - /* Initialize par */ - da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; - - da8xx_fb_var.xres = lcdc_info->xres; - da8xx_fb_var.xres_virtual = lcdc_info->xres; - - da8xx_fb_var.yres = lcdc_info->yres; - da8xx_fb_var.yres_virtual = lcdc_info->yres * LCD_NUM_BUFFERS; - da8xx_fb_var.grayscale = lcd_cfg->panel_shade == MONOCHROME ? 1 : 0; da8xx_fb_var.bits_per_pixel = lcd_cfg->bpp; - da8xx_fb_var.hsync_len = lcdc_info->hsync_len; - da8xx_fb_var.vsync_len = lcdc_info->vsync_len; - da8xx_fb_var.right_margin = lcdc_info->right_margin; - da8xx_fb_var.left_margin = lcdc_info->left_margin; - da8xx_fb_var.lower_margin = lcdc_info->lower_margin; - da8xx_fb_var.upper_margin = lcdc_info->upper_margin; - da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par); - /* Initialize fbinfo */ da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT; da8xx_fb_info->fix = da8xx_fb_fix; @@ -1433,8 +1514,8 @@ static int fb_probe(struct platform_device *device) lcdc_irq_handler = lcdc_irq_handler_rev02; } - ret = request_irq(par->irq, lcdc_irq_handler, 0, - DRIVER_NAME, par); + ret = devm_request_irq(&device->dev, par->irq, lcdc_irq_handler, 0, + DRIVER_NAME, par); if (ret) goto irq_freq; return 0; @@ -1463,12 +1544,6 @@ err_pm_runtime_disable: pm_runtime_put_sync(&device->dev); pm_runtime_disable(&device->dev); -err_ioremap: - iounmap(da8xx_fb_reg_base); - -err_request_mem: - release_mem_region(lcdc_regs->start, len); - return ret; } @@ -1546,7 +1621,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state) par->panel_power_ctrl(0); fb_set_suspend(info, 1); - lcd_disable_raster(true); + lcd_disable_raster(DA8XX_FRAME_WAIT); lcd_context_save(); pm_runtime_put_sync(&dev->dev); 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 @@ #include <linux/dmi.h> #include <linux/pci.h> #include <video/vga.h> +#include <asm/sysfb.h> static bool request_mem_succeeded = false; @@ -38,223 +39,6 @@ static struct fb_fix_screeninfo efifb_fix = { .visual = FB_VISUAL_TRUECOLOR, }; -enum { - M_I17, /* 17-Inch iMac */ - M_I20, /* 20-Inch iMac */ - M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ - M_I24, /* 24-Inch iMac */ - M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ - M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ - M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ - M_MINI, /* Mac Mini */ - M_MINI_3_1, /* Mac Mini, 3,1th gen */ - M_MINI_4_1, /* Mac Mini, 4,1th gen */ - M_MB, /* MacBook */ - M_MB_2, /* MacBook, 2nd rev. */ - M_MB_3, /* MacBook, 3rd rev. */ - M_MB_5_1, /* MacBook, 5th rev. */ - M_MB_6_1, /* MacBook, 6th rev. */ - M_MB_7_1, /* MacBook, 7th rev. */ - M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ - M_MBA, /* MacBook Air */ - M_MBA_3, /* Macbook Air, 3rd rev */ - M_MBP, /* MacBook Pro */ - M_MBP_2, /* MacBook Pro 2nd gen */ - M_MBP_2_2, /* MacBook Pro 2,2nd gen */ - M_MBP_SR, /* MacBook Pro (Santa Rosa) */ - M_MBP_4, /* MacBook Pro, 4th gen */ - M_MBP_5_1, /* MacBook Pro, 5,1th gen */ - M_MBP_5_2, /* MacBook Pro, 5,2th gen */ - M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ - M_MBP_6_1, /* MacBook Pro, 6,1th gen */ - M_MBP_6_2, /* MacBook Pro, 6,2th gen */ - M_MBP_7_1, /* MacBook Pro, 7,1th gen */ - M_MBP_8_2, /* MacBook Pro, 8,2nd gen */ - M_UNKNOWN /* placeholder */ -}; - -#define OVERRIDE_NONE 0x0 -#define OVERRIDE_BASE 0x1 -#define OVERRIDE_STRIDE 0x2 -#define OVERRIDE_HEIGHT 0x4 -#define OVERRIDE_WIDTH 0x8 - -static struct efifb_dmi_info { - char *optname; - unsigned long base; - int stride; - int width; - int height; - int flags; -} dmi_list[] __initdata = { - [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, - [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ - [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, - [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ - [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, - [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, - [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, - [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, - [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, - [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, - [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, - [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, - [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, - [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, - [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, - /* 11" Macbook Air 3,1 passes the wrong stride */ - [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, - [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, - [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ - [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, - [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, - [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, - [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, - [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, - [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, - [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, - [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, - [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, - [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, - [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } -}; - -static int set_system(const struct dmi_system_id *id); - -#define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ - { set_system, name, { \ - DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ - DMI_MATCH(DMI_PRODUCT_NAME, name) }, \ - &dmi_list[enumid] } - -static const struct dmi_system_id dmi_system_table[] __initconst = { - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), - /* At least one of these two will be right; maybe both? */ - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), - /* At least one of these two will be right; maybe both? */ - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), - /* At least one of these two will be right; maybe both? */ - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), - /* At least one of these two will be right; maybe both? */ - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3), - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2), - {}, -}; - -#define choose_value(dmivalue, fwvalue, field, flags) ({ \ - typeof(fwvalue) _ret_ = fwvalue; \ - if ((flags) & (field)) \ - _ret_ = dmivalue; \ - else if ((fwvalue) == 0) \ - _ret_ = dmivalue; \ - _ret_; \ - }) - -static int set_system(const struct dmi_system_id *id) -{ - struct efifb_dmi_info *info = id->driver_data; - - if (info->base == 0 && info->height == 0 && info->width == 0 - && info->stride == 0) - return 0; - - /* Trust the bootloader over the DMI tables */ - if (screen_info.lfb_base == 0) { -#if defined(CONFIG_PCI) - struct pci_dev *dev = NULL; - int found_bar = 0; -#endif - if (info->base) { - screen_info.lfb_base = choose_value(info->base, - screen_info.lfb_base, OVERRIDE_BASE, - info->flags); - -#if defined(CONFIG_PCI) - /* make sure that the address in the table is actually - * on a VGA device's PCI BAR */ - - for_each_pci_dev(dev) { - int i; - if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - continue; - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - resource_size_t start, end; - - start = pci_resource_start(dev, i); - if (start == 0) - break; - end = pci_resource_end(dev, i); - if (screen_info.lfb_base >= start && - screen_info.lfb_base < end) { - found_bar = 1; - } - } - } - if (!found_bar) - screen_info.lfb_base = 0; -#endif - } - } - if (screen_info.lfb_base) { - screen_info.lfb_linelength = choose_value(info->stride, - screen_info.lfb_linelength, OVERRIDE_STRIDE, - info->flags); - screen_info.lfb_width = choose_value(info->width, - screen_info.lfb_width, OVERRIDE_WIDTH, - info->flags); - screen_info.lfb_height = choose_value(info->height, - screen_info.lfb_height, OVERRIDE_HEIGHT, - info->flags); - if (screen_info.orig_video_isVGA == 0) - screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; - } else { - screen_info.lfb_linelength = 0; - screen_info.lfb_width = 0; - screen_info.lfb_height = 0; - screen_info.orig_video_isVGA = 0; - return 0; - } - - printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " - "(%dx%d, stride %d)\n", id->ident, - screen_info.lfb_base, screen_info.lfb_width, - screen_info.lfb_height, screen_info.lfb_linelength); - - - return 1; -} - static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) @@ -288,6 +72,7 @@ static void efifb_destroy(struct fb_info *info) if (request_mem_succeeded) release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); + fb_dealloc_cmap(&info->cmap); framebuffer_release(info); } @@ -312,7 +97,7 @@ void vga_set_default_device(struct pci_dev *pdev) default_vga = pdev; } -static int __init efifb_setup(char *options) +static int efifb_setup(char *options) { char *this_opt; int i; @@ -323,12 +108,12 @@ static int __init efifb_setup(char *options) if (!*this_opt) continue; for (i = 0; i < M_UNKNOWN; i++) { - if (!strcmp(this_opt, dmi_list[i].optname) && - dmi_list[i].base != 0) { - screen_info.lfb_base = dmi_list[i].base; - screen_info.lfb_linelength = dmi_list[i].stride; - screen_info.lfb_width = dmi_list[i].width; - screen_info.lfb_height = dmi_list[i].height; + if (!strcmp(this_opt, efifb_dmi_list[i].optname) && + efifb_dmi_list[i].base != 0) { + screen_info.lfb_base = efifb_dmi_list[i].base; + screen_info.lfb_linelength = efifb_dmi_list[i].stride; + screen_info.lfb_width = efifb_dmi_list[i].width; + screen_info.lfb_height = efifb_dmi_list[i].height; } } if (!strncmp(this_opt, "base:", 5)) @@ -369,13 +154,28 @@ static int __init efifb_setup(char *options) return 0; } -static int __init efifb_probe(struct platform_device *dev) +static int efifb_probe(struct platform_device *dev) { struct fb_info *info; int err; unsigned int size_vmode; unsigned int size_remap; unsigned int size_total; + char *option = NULL; + + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) + return -ENODEV; + + if (fb_get_options("efifb", &option)) + return -ENODEV; + efifb_setup(option); + + /* We don't get linelength from UGA Draw Protocol, only from + * EFI Graphics Protocol. So if it's not in DMI, and it's not + * passed in from the user, we really can't use the framebuffer. + */ + if (!screen_info.lfb_linelength) + return -ENODEV; if (!screen_info.lfb_depth) screen_info.lfb_depth = 32; @@ -539,55 +339,12 @@ err_release_mem: } static struct platform_driver efifb_driver = { - .driver = { - .name = "efifb", + .driver = { + .name = "efi-framebuffer", + .owner = THIS_MODULE, }, + .probe = efifb_probe, }; -static struct platform_device efifb_device = { - .name = "efifb", -}; - -static int __init efifb_init(void) -{ - int ret; - char *option = NULL; - - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || - !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) - dmi_check_system(dmi_system_table); - - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) - return -ENODEV; - - if (fb_get_options("efifb", &option)) - return -ENODEV; - efifb_setup(option); - - /* We don't get linelength from UGA Draw Protocol, only from - * EFI Graphics Protocol. So if it's not in DMI, and it's not - * passed in from the user, we really can't use the framebuffer. - */ - if (!screen_info.lfb_linelength) - return -ENODEV; - - ret = platform_device_register(&efifb_device); - if (ret) - return ret; - - /* - * This is not just an optimization. We will interfere - * with a real driver if we get reprobed, so don't allow - * it. - */ - ret = platform_driver_probe(&efifb_driver, efifb_probe); - if (ret) { - platform_device_unregister(&efifb_device); - return ret; - } - - return ret; -} -module_init(efifb_init); - +module_platform_driver(efifb_driver); 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 @@ #include <video/exynos_mipi_dsim.h> #include "exynos_mipi_dsi_regs.h" +#include "exynos_mipi_dsi_lowlevel.h" void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim) { 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) rc = -ENODEV; goto out; } - if (cmap->start < 0 || (!info->fbops->fb_setcolreg && - !info->fbops->fb_setcmap)) { - rc = -EINVAL; - goto out1; - } + rc = fb_set_cmap(&umap, info); -out1: unlock_fb_info(info); out: 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 @@ #define FBPIXMAPSIZE (1024 * 8) static DEFINE_MUTEX(registration_lock); + struct fb_info *registered_fb[FB_MAX] __read_mostly; +EXPORT_SYMBOL(registered_fb); + int num_registered_fb __read_mostly; +EXPORT_SYMBOL(num_registered_fb); static struct fb_info *get_fb_info(unsigned int idx) { @@ -182,6 +186,7 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size return addr; } +EXPORT_SYMBOL(fb_get_buffer_offset); #ifdef CONFIG_LOGO @@ -669,6 +674,7 @@ int fb_show_logo(struct fb_info *info, int rotate) int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; } int fb_show_logo(struct fb_info *info, int rotate) { return 0; } #endif /* CONFIG_LOGO */ +EXPORT_SYMBOL(fb_show_logo); static void *fb_seq_start(struct seq_file *m, loff_t *pos) { @@ -909,6 +915,7 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) info->var.vmode &= ~FB_VMODE_YWRAP; return 0; } +EXPORT_SYMBOL(fb_pan_display); static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, u32 activate) @@ -1042,6 +1049,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) done: return ret; } +EXPORT_SYMBOL(fb_set_var); int fb_blank(struct fb_info *info, int blank) @@ -1073,6 +1081,7 @@ fb_blank(struct fb_info *info, int blank) return ret; } +EXPORT_SYMBOL(fb_blank); static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) @@ -1745,6 +1754,7 @@ register_framebuffer(struct fb_info *fb_info) return ret; } +EXPORT_SYMBOL(register_framebuffer); /** * unregister_framebuffer - releases a frame buffer device @@ -1773,6 +1783,7 @@ unregister_framebuffer(struct fb_info *fb_info) return ret; } +EXPORT_SYMBOL(unregister_framebuffer); /** * fb_set_suspend - low level driver signals suspend @@ -1796,6 +1807,7 @@ void fb_set_suspend(struct fb_info *info, int state) fb_notifier_call_chain(FB_EVENT_RESUME, &event); } } +EXPORT_SYMBOL(fb_set_suspend); /** * fbmem_init - init frame buffer subsystem @@ -1912,6 +1924,7 @@ int fb_get_options(const char *name, char **option) return retval; } +EXPORT_SYMBOL(fb_get_options); #ifndef MODULE /** @@ -1959,20 +1972,4 @@ static int __init video_setup(char *options) __setup("video=", video_setup); #endif - /* - * Visible symbols for modules - */ - -EXPORT_SYMBOL(register_framebuffer); -EXPORT_SYMBOL(unregister_framebuffer); -EXPORT_SYMBOL(num_registered_fb); -EXPORT_SYMBOL(registered_fb); -EXPORT_SYMBOL(fb_show_logo); -EXPORT_SYMBOL(fb_set_var); -EXPORT_SYMBOL(fb_blank); -EXPORT_SYMBOL(fb_pan_display); -EXPORT_SYMBOL(fb_get_buffer_offset); -EXPORT_SYMBOL(fb_set_suspend); -EXPORT_SYMBOL(fb_get_options); - 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 @@ */ #include <linux/bitops.h> +#include <linux/bug.h> #include <linux/errno.h> #include <linux/export.h> #include <linux/hdmi.h> @@ -52,7 +53,7 @@ int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame) frame->type = HDMI_INFOFRAME_TYPE_AVI; frame->version = 2; - frame->length = 13; + frame->length = HDMI_AVI_INFOFRAME_SIZE; return 0; } @@ -83,7 +84,7 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, if (size < length) return -ENOSPC; - memset(buffer, 0, length); + memset(buffer, 0, size); ptr[0] = frame->type; ptr[1] = frame->version; @@ -95,13 +96,18 @@ ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3); - if (frame->active_info_valid) + /* + * Data byte 1, bit 4 has to be set if we provide the active format + * aspect ratio + */ + if (frame->active_aspect & 0xf) ptr[0] |= BIT(4); - if (frame->horizontal_bar_valid) + /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */ + if (frame->top_bar || frame->bottom_bar) ptr[0] |= BIT(3); - if (frame->vertical_bar_valid) + if (frame->left_bar || frame->right_bar) ptr[0] |= BIT(2); ptr[1] = ((frame->colorimetry & 0x3) << 6) | @@ -151,7 +157,7 @@ int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, frame->type = HDMI_INFOFRAME_TYPE_SPD; frame->version = 1; - frame->length = 25; + frame->length = HDMI_SPD_INFOFRAME_SIZE; strncpy(frame->vendor, vendor, sizeof(frame->vendor)); strncpy(frame->product, product, sizeof(frame->product)); @@ -185,7 +191,7 @@ ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, if (size < length) return -ENOSPC; - memset(buffer, 0, length); + memset(buffer, 0, size); ptr[0] = frame->type; ptr[1] = frame->version; @@ -218,7 +224,7 @@ int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame) frame->type = HDMI_INFOFRAME_TYPE_AUDIO; frame->version = 1; - frame->length = 10; + frame->length = HDMI_AUDIO_INFOFRAME_SIZE; return 0; } @@ -250,7 +256,7 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, if (size < length) return -ENOSPC; - memset(buffer, 0, length); + memset(buffer, 0, size); if (frame->channels >= 2) channels = frame->channels - 1; @@ -282,9 +288,33 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, EXPORT_SYMBOL(hdmi_audio_infoframe_pack); /** - * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary - * buffer + * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe * @frame: HDMI vendor infoframe + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) +{ + memset(frame, 0, sizeof(*frame)); + + frame->type = HDMI_INFOFRAME_TYPE_VENDOR; + frame->version = 1; + + frame->oui = HDMI_IEEE_OUI; + + /* + * 0 is a valid value for s3d_struct, so we use a special "not set" + * value + */ + frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID; + + return 0; +} +EXPORT_SYMBOL(hdmi_vendor_infoframe_init); + +/** + * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer + * @frame: HDMI infoframe * @buffer: destination buffer * @size: size of buffer * @@ -297,27 +327,110 @@ EXPORT_SYMBOL(hdmi_audio_infoframe_pack); * error code on failure. */ ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, - void *buffer, size_t size) + void *buffer, size_t size) { u8 *ptr = buffer; size_t length; + /* empty info frame */ + if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID) + return -EINVAL; + + /* only one of those can be supplied */ + if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) + return -EINVAL; + + /* for side by side (half) we also need to provide 3D_Ext_Data */ + if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) + frame->length = 6; + else + frame->length = 5; + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; if (size < length) return -ENOSPC; - memset(buffer, 0, length); + memset(buffer, 0, size); ptr[0] = frame->type; ptr[1] = frame->version; ptr[2] = frame->length; ptr[3] = 0; /* checksum */ - memcpy(&ptr[HDMI_INFOFRAME_HEADER_SIZE], frame->data, frame->length); + /* HDMI OUI */ + ptr[4] = 0x03; + ptr[5] = 0x0c; + ptr[6] = 0x00; + + if (frame->vic) { + ptr[7] = 0x1 << 5; /* video format */ + ptr[8] = frame->vic; + } else { + ptr[7] = 0x2 << 5; /* video format */ + ptr[8] = (frame->s3d_struct & 0xf) << 4; + if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) + ptr[9] = (frame->s3d_ext_data & 0xf) << 4; + } hdmi_infoframe_checksum(buffer, length); return length; } EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); + +/* + * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer + */ +static ssize_t +hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, + void *buffer, size_t size) +{ + /* we only know about HDMI vendor infoframes */ + if (frame->any.oui != HDMI_IEEE_OUI) + return -EINVAL; + + return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size); +} + +/** + * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer + * @frame: HDMI infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Packs the information contained in the @frame structure into a binary + * representation that can be written into the corresponding controller + * registers. Also computes the checksum as required by section 5.3.5 of + * the HDMI 1.4 specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t +hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) +{ + ssize_t length; + + switch (frame->any.type) { + case HDMI_INFOFRAME_TYPE_AVI: + length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size); + break; + case HDMI_INFOFRAME_TYPE_SPD: + length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size); + break; + case HDMI_INFOFRAME_TYPE_AUDIO: + length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size); + break; + case HDMI_INFOFRAME_TYPE_VENDOR: + length = hdmi_vendor_any_infoframe_pack(&frame->vendor, + buffer, size); + break; + default: + WARN(1, "Bad infoframe type %d\n", frame->any.type); + length = -EINVAL; + } + + return length; +} +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); module_exit(hvfb_drv_exit); MODULE_LICENSE("GPL"); -MODULE_VERSION(HV_DRV_VERSION); 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 return -1; } - minfo = kmalloc(sizeof(*minfo), GFP_KERNEL); + minfo = kzalloc(sizeof(*minfo), GFP_KERNEL); if (!minfo) return -1; - memset(minfo, 0, sizeof(*minfo)); minfo->pcidev = pdev; minfo->dead = 0; diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index dc09ebe4aba5..d250ed0f806d 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -46,7 +46,6 @@ #include <linux/clk.h> #include <linux/dma-mapping.h> #include <linux/io.h> -#include <linux/pinctrl/consumer.h> #include <linux/fb.h> #include <linux/regulator/consumer.h> #include <video/of_display_timing.h> @@ -851,18 +850,11 @@ static int mxsfb_probe(struct platform_device *pdev) struct mxsfb_info *host; struct fb_info *fb_info; struct fb_modelist *modelist; - struct pinctrl *pinctrl; int ret; if (of_id) pdev->id_entry = of_id->data; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Cannot get memory IO resource\n"); - return -ENODEV; - } - fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev); if (!fb_info) { dev_err(&pdev->dev, "Failed to allocate fbdev\n"); @@ -871,6 +863,7 @@ static int mxsfb_probe(struct platform_device *pdev) host = to_imxfb_host(fb_info); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); host->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(host->base)) { ret = PTR_ERR(host->base); @@ -882,12 +875,6 @@ static int mxsfb_probe(struct platform_device *pdev) host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(pinctrl); - goto fb_release; - } - host->clk = devm_clk_get(&host->pdev->dev, NULL); if (IS_ERR(host->clk)) { ret = PTR_ERR(host->clk); 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 source "drivers/video/omap2/dss/Kconfig" source "drivers/video/omap2/omapfb/Kconfig" -source "drivers/video/omap2/displays/Kconfig" source "drivers/video/omap2/displays-new/Kconfig" 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 @@ obj-$(CONFIG_OMAP2_VRFB) += vrfb.o obj-$(CONFIG_OMAP2_DSS) += dss/ -obj-y += displays/ obj-y += displays-new/ obj-$(CONFIG_FB_OMAP2) += omapfb/ 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, if (r) return r; - dst->output = dssdev; - dssdev->device = dst; + dst->src = dssdev; + dssdev->dst = dst; return 0; } @@ -59,12 +59,12 @@ static void tfp410_disconnect(struct omap_dss_device *dssdev, if (!omapdss_device_is_connected(dssdev)) return; - WARN_ON(dst != dssdev->device); - if (dst != dssdev->device) + WARN_ON(dst != dssdev->dst); + if (dst != dssdev->dst) return; - dst->output = NULL; - dssdev->device = NULL; + dst->src = NULL; + dssdev->dst = NULL; in->ops.dpi->disconnect(in, &ddata->dssdev); } @@ -244,7 +244,7 @@ static int __exit tfp410_remove(struct platform_device *pdev) WARN_ON(omapdss_device_is_connected(dssdev)); if (omapdss_device_is_connected(dssdev)) - tfp410_disconnect(dssdev, dssdev->device); + tfp410_disconnect(dssdev, dssdev->dst); omap_dss_put_device(in); 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, if (r) return r; - dst->output = dssdev; - dssdev->device = dst; + dst->src = dssdev; + dssdev->dst = dst; INIT_COMPLETION(ddata->hpd_completion); @@ -95,15 +95,15 @@ static void tpd_disconnect(struct omap_dss_device *dssdev, struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *in = ddata->in; - WARN_ON(dst != dssdev->device); + WARN_ON(dst != dssdev->dst); - if (dst != dssdev->device) + if (dst != dssdev->dst) return; gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 0); - dst->output = NULL; - dssdev->device = NULL; + dst->src = NULL; + dssdev->dst = NULL; in->ops.hdmi->disconnect(in, &ddata->dssdev); } @@ -372,7 +372,7 @@ static int __exit tpd_remove(struct platform_device *pdev) WARN_ON(omapdss_device_is_connected(dssdev)); if (omapdss_device_is_connected(dssdev)) - tpd_disconnect(dssdev, dssdev->device); + tpd_disconnect(dssdev, dssdev->dst); omap_dss_put_device(in); 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 @@ -menu "OMAP2/3 Display Device Drivers (old device model)" - depends on OMAP2_DSS - -config PANEL_GENERIC_DPI - tristate "Generic DPI Panel" - depends on OMAP2_DSS_DPI - help - Generic DPI panel driver. - Supports DVI output for Beagle and OMAP3 SDP. - Supports LCD Panel used in TI SDP3430 and EVM boards, - OMAP3517 EVM boards and CM-T35. - -config PANEL_TFP410 - tristate "TFP410 DPI-to-DVI chip" - depends on OMAP2_DSS_DPI && I2C - help - Driver for TFP410 DPI-to-DVI chip. The driver uses i2c to read EDID - information from the monitor. - -config PANEL_LGPHILIPS_LB035Q02 - tristate "LG.Philips LB035Q02 LCD Panel" - depends on OMAP2_DSS_DPI && SPI - help - LCD Panel used on the Gumstix Overo Palo35 - -config PANEL_SHARP_LS037V7DW01 - tristate "Sharp LS037V7DW01 LCD Panel" - depends on OMAP2_DSS_DPI - depends on BACKLIGHT_CLASS_DEVICE - help - LCD Panel used in TI's SDP3430 and EVM boards - -config PANEL_NEC_NL8048HL11_01B - tristate "NEC NL8048HL11-01B Panel" - depends on OMAP2_DSS_DPI - depends on SPI - depends on BACKLIGHT_CLASS_DEVICE - help - This NEC NL8048HL11-01B panel is TFT LCD - used in the Zoom2/3/3630 sdp boards. - -config PANEL_PICODLP - tristate "TI PICO DLP mini-projector" - depends on OMAP2_DSS_DPI && I2C - help - A mini-projector used in TI's SDP4430 and EVM boards - For more info please visit http://www.dlp.com/projector/ - -config PANEL_TAAL - tristate "Taal DSI Panel" - depends on OMAP2_DSS_DSI - depends on BACKLIGHT_CLASS_DEVICE - help - Taal DSI command mode panel from TPO. - -config PANEL_TPO_TD043MTEA1 - tristate "TPO TD043MTEA1 LCD Panel" - depends on OMAP2_DSS_DPI && SPI - help - LCD Panel used in OMAP3 Pandora - -config PANEL_ACX565AKM - tristate "ACX565AKM Panel" - depends on OMAP2_DSS_SDI && SPI - depends on BACKLIGHT_CLASS_DEVICE - help - This is the LCD panel used on Nokia N900 - -config PANEL_N8X0 - tristate "N8X0 Panel" - depends on OMAP2_DSS_RFBI && SPI - depends on BACKLIGHT_CLASS_DEVICE - help - This is the LCD panel used on Nokia N8x0 -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 @@ -obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o -obj-$(CONFIG_PANEL_TFP410) += panel-tfp410.o -obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o -obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o -obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o - -obj-$(CONFIG_PANEL_TAAL) += panel-taal.o -obj-$(CONFIG_PANEL_PICODLP) += panel-picodlp.o -obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o -obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o -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 @@ -/* - * Support for ACX565AKM LCD Panel used on Nokia N900 - * - * Copyright (C) 2010 Nokia Corporation - * - * Original Driver Author: Imre Deak <imre.deak@nokia.com> - * Based on panel-generic.c by Tomi Valkeinen <tomi.valkeinen@nokia.com> - * Adapted to new DSS2 framework: Roger Quadros <roger.quadros@nokia.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/jiffies.h> -#include <linux/sched.h> -#include <linux/backlight.h> -#include <linux/fb.h> -#include <linux/gpio.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#define MIPID_CMD_READ_DISP_ID 0x04 -#define MIPID_CMD_READ_RED 0x06 -#define MIPID_CMD_READ_GREEN 0x07 -#define MIPID_CMD_READ_BLUE 0x08 -#define MIPID_CMD_READ_DISP_STATUS 0x09 -#define MIPID_CMD_RDDSDR 0x0F -#define MIPID_CMD_SLEEP_IN 0x10 -#define MIPID_CMD_SLEEP_OUT 0x11 -#define MIPID_CMD_DISP_OFF 0x28 -#define MIPID_CMD_DISP_ON 0x29 -#define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51 -#define MIPID_CMD_READ_DISP_BRIGHTNESS 0x52 -#define MIPID_CMD_WRITE_CTRL_DISP 0x53 - -#define CTRL_DISP_BRIGHTNESS_CTRL_ON (1 << 5) -#define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4) -#define CTRL_DISP_BACKLIGHT_ON (1 << 2) -#define CTRL_DISP_AUTO_BRIGHTNESS_ON (1 << 1) - -#define MIPID_CMD_READ_CTRL_DISP 0x54 -#define MIPID_CMD_WRITE_CABC 0x55 -#define MIPID_CMD_READ_CABC 0x56 - -#define MIPID_VER_LPH8923 3 -#define MIPID_VER_LS041Y3 4 -#define MIPID_VER_L4F00311 8 -#define MIPID_VER_ACX565AKM 9 - -struct acx565akm_device { - char *name; - int enabled; - int model; - int revision; - u8 display_id[3]; - unsigned has_bc:1; - unsigned has_cabc:1; - unsigned cabc_mode; - unsigned long hw_guard_end; /* next value of jiffies - when we can issue the - next sleep in/out command */ - unsigned long hw_guard_wait; /* max guard time in jiffies */ - - struct spi_device *spi; - struct mutex mutex; - - struct omap_dss_device *dssdev; - struct backlight_device *bl_dev; -}; - -static struct acx565akm_device acx_dev; -static int acx565akm_bl_update_status(struct backlight_device *dev); - -/*--------------------MIPID interface-----------------------------*/ - -static void acx565akm_transfer(struct acx565akm_device *md, int cmd, - const u8 *wbuf, int wlen, u8 *rbuf, int rlen) -{ - struct spi_message m; - struct spi_transfer *x, xfer[5]; - int r; - - BUG_ON(md->spi == NULL); - - spi_message_init(&m); - - memset(xfer, 0, sizeof(xfer)); - x = &xfer[0]; - - cmd &= 0xff; - x->tx_buf = &cmd; - x->bits_per_word = 9; - x->len = 2; - - if (rlen > 1 && wlen == 0) { - /* - * Between the command and the response data there is a - * dummy clock cycle. Add an extra bit after the command - * word to account for this. - */ - x->bits_per_word = 10; - cmd <<= 1; - } - spi_message_add_tail(x, &m); - - if (wlen) { - x++; - x->tx_buf = wbuf; - x->len = wlen; - x->bits_per_word = 9; - spi_message_add_tail(x, &m); - } - - if (rlen) { - x++; - x->rx_buf = rbuf; - x->len = rlen; - spi_message_add_tail(x, &m); - } - - r = spi_sync(md->spi, &m); - if (r < 0) - dev_dbg(&md->spi->dev, "spi_sync %d\n", r); -} - -static inline void acx565akm_cmd(struct acx565akm_device *md, int cmd) -{ - acx565akm_transfer(md, cmd, NULL, 0, NULL, 0); -} - -static inline void acx565akm_write(struct acx565akm_device *md, - int reg, const u8 *buf, int len) -{ - acx565akm_transfer(md, reg, buf, len, NULL, 0); -} - -static inline void acx565akm_read(struct acx565akm_device *md, - int reg, u8 *buf, int len) -{ - acx565akm_transfer(md, reg, NULL, 0, buf, len); -} - -static void hw_guard_start(struct acx565akm_device *md, int guard_msec) -{ - md->hw_guard_wait = msecs_to_jiffies(guard_msec); - md->hw_guard_end = jiffies + md->hw_guard_wait; -} - -static void hw_guard_wait(struct acx565akm_device *md) -{ - unsigned long wait = md->hw_guard_end - jiffies; - - if ((long)wait > 0 && wait <= md->hw_guard_wait) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(wait); - } -} - -/*----------------------MIPID wrappers----------------------------*/ - -static void set_sleep_mode(struct acx565akm_device *md, int on) -{ - int cmd; - - if (on) - cmd = MIPID_CMD_SLEEP_IN; - else - cmd = MIPID_CMD_SLEEP_OUT; - /* - * We have to keep 120msec between sleep in/out commands. - * (8.2.15, 8.2.16). - */ - hw_guard_wait(md); - acx565akm_cmd(md, cmd); - hw_guard_start(md, 120); -} - -static void set_display_state(struct acx565akm_device *md, int enabled) -{ - int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF; - - acx565akm_cmd(md, cmd); -} - -static int panel_enabled(struct acx565akm_device *md) -{ - u32 disp_status; - int enabled; - - acx565akm_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4); - disp_status = __be32_to_cpu(disp_status); - enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10)); - dev_dbg(&md->spi->dev, - "LCD panel %senabled by bootloader (status 0x%04x)\n", - enabled ? "" : "not ", disp_status); - return enabled; -} - -static int panel_detect(struct acx565akm_device *md) -{ - acx565akm_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3); - dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n", - md->display_id[0], md->display_id[1], md->display_id[2]); - - switch (md->display_id[0]) { - case 0x10: - md->model = MIPID_VER_ACX565AKM; - md->name = "acx565akm"; - md->has_bc = 1; - md->has_cabc = 1; - break; - case 0x29: - md->model = MIPID_VER_L4F00311; - md->name = "l4f00311"; - break; - case 0x45: - md->model = MIPID_VER_LPH8923; - md->name = "lph8923"; - break; - case 0x83: - md->model = MIPID_VER_LS041Y3; - md->name = "ls041y3"; - break; - default: - md->name = "unknown"; - dev_err(&md->spi->dev, "invalid display ID\n"); - return -ENODEV; - } - - md->revision = md->display_id[1]; - - dev_info(&md->spi->dev, "omapfb: %s rev %02x LCD detected\n", - md->name, md->revision); - - return 0; -} - -/*----------------------Backlight Control-------------------------*/ - -static void enable_backlight_ctrl(struct acx565akm_device *md, int enable) -{ - u16 ctrl; - - acx565akm_read(md, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1); - if (enable) { - ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON | - CTRL_DISP_BACKLIGHT_ON; - } else { - ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON | - CTRL_DISP_BACKLIGHT_ON); - } - - ctrl |= 1 << 8; - acx565akm_write(md, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2); -} - -static void set_cabc_mode(struct acx565akm_device *md, unsigned mode) -{ - u16 cabc_ctrl; - - md->cabc_mode = mode; - if (!md->enabled) - return; - cabc_ctrl = 0; - acx565akm_read(md, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1); - cabc_ctrl &= ~3; - cabc_ctrl |= (1 << 8) | (mode & 3); - acx565akm_write(md, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2); -} - -static unsigned get_cabc_mode(struct acx565akm_device *md) -{ - return md->cabc_mode; -} - -static unsigned get_hw_cabc_mode(struct acx565akm_device *md) -{ - u8 cabc_ctrl; - - acx565akm_read(md, MIPID_CMD_READ_CABC, &cabc_ctrl, 1); - return cabc_ctrl & 3; -} - -static void acx565akm_set_brightness(struct acx565akm_device *md, int level) -{ - int bv; - - bv = level | (1 << 8); - acx565akm_write(md, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2); - - if (level) - enable_backlight_ctrl(md, 1); - else - enable_backlight_ctrl(md, 0); -} - -static int acx565akm_get_actual_brightness(struct acx565akm_device *md) -{ - u8 bv; - - acx565akm_read(md, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1); - - return bv; -} - - -static int acx565akm_bl_update_status(struct backlight_device *dev) -{ - struct acx565akm_device *md = dev_get_drvdata(&dev->dev); - int r; - int level; - - dev_dbg(&md->spi->dev, "%s\n", __func__); - - mutex_lock(&md->mutex); - - if (dev->props.fb_blank == FB_BLANK_UNBLANK && - dev->props.power == FB_BLANK_UNBLANK) - level = dev->props.brightness; - else - level = 0; - - r = 0; - if (md->has_bc) - acx565akm_set_brightness(md, level); - else - r = -ENODEV; - - mutex_unlock(&md->mutex); - - return r; -} - -static int acx565akm_bl_get_intensity(struct backlight_device *dev) -{ - struct acx565akm_device *md = dev_get_drvdata(&dev->dev); - - dev_dbg(&dev->dev, "%s\n", __func__); - - if (!md->has_bc) - return -ENODEV; - - if (dev->props.fb_blank == FB_BLANK_UNBLANK && - dev->props.power == FB_BLANK_UNBLANK) { - if (md->has_bc) - return acx565akm_get_actual_brightness(md); - else - return dev->props.brightness; - } - - return 0; -} - -static const struct backlight_ops acx565akm_bl_ops = { - .get_brightness = acx565akm_bl_get_intensity, - .update_status = acx565akm_bl_update_status, -}; - -/*--------------------Auto Brightness control via Sysfs---------------------*/ - -static const char *cabc_modes[] = { - "off", /* always used when CABC is not supported */ - "ui", - "still-image", - "moving-image", -}; - -static ssize_t show_cabc_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acx565akm_device *md = dev_get_drvdata(dev); - const char *mode_str; - int mode; - int len; - - if (!md->has_cabc) - mode = 0; - else - mode = get_cabc_mode(md); - mode_str = "unknown"; - if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes)) - mode_str = cabc_modes[mode]; - len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str); - - return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1; -} - -static ssize_t store_cabc_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct acx565akm_device *md = dev_get_drvdata(dev); - int i; - - for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { - const char *mode_str = cabc_modes[i]; - int cmp_len = strlen(mode_str); - - if (count > 0 && buf[count - 1] == '\n') - count--; - if (count != cmp_len) - continue; - - if (strncmp(buf, mode_str, cmp_len) == 0) - break; - } - - if (i == ARRAY_SIZE(cabc_modes)) - return -EINVAL; - - if (!md->has_cabc && i != 0) - return -EINVAL; - - mutex_lock(&md->mutex); - set_cabc_mode(md, i); - mutex_unlock(&md->mutex); - - return count; -} - -static ssize_t show_cabc_available_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acx565akm_device *md = dev_get_drvdata(dev); - int len; - int i; - - if (!md->has_cabc) - return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]); - - for (i = 0, len = 0; - len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++) - len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s", - i ? " " : "", cabc_modes[i], - i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : ""); - - return len < PAGE_SIZE ? len : PAGE_SIZE - 1; -} - -static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, - show_cabc_mode, store_cabc_mode); -static DEVICE_ATTR(cabc_available_modes, S_IRUGO, - show_cabc_available_modes, NULL); - -static struct attribute *bldev_attrs[] = { - &dev_attr_cabc_mode.attr, - &dev_attr_cabc_available_modes.attr, - NULL, -}; - -static struct attribute_group bldev_attr_group = { - .attrs = bldev_attrs, -}; - - -/*---------------------------ACX Panel----------------------------*/ - -static int acx_get_recommended_bpp(struct omap_dss_device *dssdev) -{ - return 16; -} - -static struct omap_video_timings acx_panel_timings = { - .x_res = 800, - .y_res = 480, - .pixel_clock = 24000, - .hfp = 28, - .hsw = 4, - .hbp = 24, - .vfp = 3, - .vsw = 3, - .vbp = 4, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, -}; - -static struct panel_acx565akm_data *get_panel_data(struct omap_dss_device *dssdev) -{ - return (struct panel_acx565akm_data *) dssdev->data; -} - -static int acx_panel_probe(struct omap_dss_device *dssdev) -{ - int r; - struct acx565akm_device *md = &acx_dev; - struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); - struct backlight_device *bldev; - int max_brightness, brightness; - struct backlight_properties props; - - dev_dbg(dssdev->dev, "%s\n", __func__); - - if (!panel_data) - return -EINVAL; - - /* FIXME AC bias ? */ - dssdev->panel.timings = acx_panel_timings; - - if (gpio_is_valid(panel_data->reset_gpio)) { - r = devm_gpio_request_one(dssdev->dev, panel_data->reset_gpio, - GPIOF_OUT_INIT_LOW, "lcd reset"); - if (r) - return r; - } - - if (gpio_is_valid(panel_data->reset_gpio)) - gpio_set_value(panel_data->reset_gpio, 1); - - /* - * After reset we have to wait 5 msec before the first - * command can be sent. - */ - msleep(5); - - md->enabled = panel_enabled(md); - - r = panel_detect(md); - if (r) { - dev_err(dssdev->dev, "%s panel detect error\n", __func__); - if (!md->enabled && gpio_is_valid(panel_data->reset_gpio)) - gpio_set_value(panel_data->reset_gpio, 0); - - return r; - } - - mutex_lock(&acx_dev.mutex); - acx_dev.dssdev = dssdev; - mutex_unlock(&acx_dev.mutex); - - if (!md->enabled) { - if (gpio_is_valid(panel_data->reset_gpio)) - gpio_set_value(panel_data->reset_gpio, 0); - } - - /*------- Backlight control --------*/ - - memset(&props, 0, sizeof(props)); - props.fb_blank = FB_BLANK_UNBLANK; - props.power = FB_BLANK_UNBLANK; - props.type = BACKLIGHT_RAW; - - bldev = backlight_device_register("acx565akm", &md->spi->dev, - md, &acx565akm_bl_ops, &props); - md->bl_dev = bldev; - if (md->has_cabc) { - r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group); - if (r) { - dev_err(&bldev->dev, - "%s failed to create sysfs files\n", __func__); - backlight_device_unregister(bldev); - return r; - } - md->cabc_mode = get_hw_cabc_mode(md); - } - - max_brightness = 255; - - if (md->has_bc) - brightness = acx565akm_get_actual_brightness(md); - else - brightness = 0; - - bldev->props.max_brightness = max_brightness; - bldev->props.brightness = brightness; - - acx565akm_bl_update_status(bldev); - return 0; -} - -static void acx_panel_remove(struct omap_dss_device *dssdev) -{ - struct acx565akm_device *md = &acx_dev; - - dev_dbg(dssdev->dev, "%s\n", __func__); - sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group); - backlight_device_unregister(md->bl_dev); - mutex_lock(&acx_dev.mutex); - acx_dev.dssdev = NULL; - mutex_unlock(&acx_dev.mutex); -} - -static int acx_panel_power_on(struct omap_dss_device *dssdev) -{ - struct acx565akm_device *md = &acx_dev; - struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); - int r; - - dev_dbg(dssdev->dev, "%s\n", __func__); - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - mutex_lock(&md->mutex); - - omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs); - - r = omapdss_sdi_display_enable(dssdev); - if (r) { - pr_err("%s sdi enable failed\n", __func__); - goto fail_unlock; - } - - /*FIXME tweak me */ - msleep(50); - - if (gpio_is_valid(panel_data->reset_gpio)) - gpio_set_value(panel_data->reset_gpio, 1); - - if (md->enabled) { - dev_dbg(&md->spi->dev, "panel already enabled\n"); - mutex_unlock(&md->mutex); - return 0; - } - - /* - * We have to meet all the following delay requirements: - * 1. tRW: reset pulse width 10usec (7.12.1) - * 2. tRT: reset cancel time 5msec (7.12.1) - * 3. Providing PCLK,HS,VS signals for 2 frames = ~50msec worst - * case (7.6.2) - * 4. 120msec before the sleep out command (7.12.1) - */ - msleep(120); - - set_sleep_mode(md, 0); - md->enabled = 1; - - /* 5msec between sleep out and the next command. (8.2.16) */ - msleep(5); - set_display_state(md, 1); - set_cabc_mode(md, md->cabc_mode); - - mutex_unlock(&md->mutex); - - return acx565akm_bl_update_status(md->bl_dev); - -fail_unlock: - mutex_unlock(&md->mutex); - return r; -} - -static void acx_panel_power_off(struct omap_dss_device *dssdev) -{ - struct acx565akm_device *md = &acx_dev; - struct panel_acx565akm_data *panel_data = get_panel_data(dssdev); - - dev_dbg(dssdev->dev, "%s\n", __func__); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - mutex_lock(&md->mutex); - - if (!md->enabled) { - mutex_unlock(&md->mutex); - return; - } - set_display_state(md, 0); - set_sleep_mode(md, 1); - md->enabled = 0; - /* - * We have to provide PCLK,HS,VS signals for 2 frames (worst case - * ~50msec) after sending the sleep in command and asserting the - * reset signal. We probably could assert the reset w/o the delay - * but we still delay to avoid possible artifacts. (7.6.1) - */ - msleep(50); - - if (gpio_is_valid(panel_data->reset_gpio)) - gpio_set_value(panel_data->reset_gpio, 0); - - /* FIXME need to tweak this delay */ - msleep(100); - - omapdss_sdi_display_disable(dssdev); - - mutex_unlock(&md->mutex); -} - -static int acx_panel_enable(struct omap_dss_device *dssdev) -{ - int r; - - dev_dbg(dssdev->dev, "%s\n", __func__); - r = acx_panel_power_on(dssdev); - - if (r) - return r; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - return 0; -} - -static void acx_panel_disable(struct omap_dss_device *dssdev) -{ - dev_dbg(dssdev->dev, "%s\n", __func__); - acx_panel_power_off(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -} - -static void acx_panel_set_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - omapdss_sdi_set_timings(dssdev, timings); - - dssdev->panel.timings = *timings; -} - -static int acx_panel_check_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - return 0; -} - - -static struct omap_dss_driver acx_panel_driver = { - .probe = acx_panel_probe, - .remove = acx_panel_remove, - - .enable = acx_panel_enable, - .disable = acx_panel_disable, - - .set_timings = acx_panel_set_timings, - .check_timings = acx_panel_check_timings, - - .get_recommended_bpp = acx_get_recommended_bpp, - - .driver = { - .name = "panel-acx565akm", - .owner = THIS_MODULE, - }, -}; - -/*--------------------SPI probe-------------------------*/ - -static int acx565akm_spi_probe(struct spi_device *spi) -{ - struct acx565akm_device *md = &acx_dev; - - dev_dbg(&spi->dev, "%s\n", __func__); - - spi->mode = SPI_MODE_3; - md->spi = spi; - mutex_init(&md->mutex); - dev_set_drvdata(&spi->dev, md); - - omap_dss_register_driver(&acx_panel_driver); - - return 0; -} - -static int acx565akm_spi_remove(struct spi_device *spi) -{ - struct acx565akm_device *md = dev_get_drvdata(&spi->dev); - - dev_dbg(&md->spi->dev, "%s\n", __func__); - omap_dss_unregister_driver(&acx_panel_driver); - - return 0; -} - -static struct spi_driver acx565akm_spi_driver = { - .driver = { - .name = "acx565akm", - .owner = THIS_MODULE, - }, - .probe = acx565akm_spi_probe, - .remove = acx565akm_spi_remove, -}; - -module_spi_driver(acx565akm_spi_driver); - -MODULE_AUTHOR("Nokia Corporation"); -MODULE_DESCRIPTION("acx565akm LCD Driver"); -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 @@ -/* - * Generic DPI Panels support - * - * Copyright (C) 2010 Canonical Ltd. - * Author: Bryan Wu <bryan.wu@canonical.com> - * - * LCD panel driver for Sharp LQ043T1DG01 - * - * Copyright (C) 2009 Texas Instruments Inc - * Author: Vaibhav Hiremath <hvaibhav@ti.com> - * - * LCD panel driver for Toppoly TDO35S - * - * Copyright (C) 2009 CompuLab, Ltd. - * Author: Mike Rapoport <mike@compulab.co.il> - * - * Copyright (C) 2008 Nokia Corporation - * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <video/omapdss.h> - -#include <video/omap-panel-data.h> - -struct panel_config { - struct omap_video_timings timings; - - int power_on_delay; - int power_off_delay; - - /* - * Used to match device to panel configuration - * when use generic panel driver - */ - const char *name; -}; - -/* Panel configurations */ -static struct panel_config generic_dpi_panels[] = { - /* Sharp LQ043T1DG01 */ - { - { - .x_res = 480, - .y_res = 272, - - .pixel_clock = 9000, - - .hsw = 42, - .hfp = 3, - .hbp = 2, - - .vsw = 11, - .vfp = 3, - .vbp = 2, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_LOW, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .power_on_delay = 50, - .power_off_delay = 100, - .name = "sharp_lq", - }, - - /* Sharp LS037V7DW01 */ - { - { - .x_res = 480, - .y_res = 640, - - .pixel_clock = 19200, - - .hsw = 2, - .hfp = 1, - .hbp = 28, - - .vsw = 1, - .vfp = 1, - .vbp = 1, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .power_on_delay = 50, - .power_off_delay = 100, - .name = "sharp_ls", - }, - - /* Toppoly TDO35S */ - { - { - .x_res = 480, - .y_res = 640, - - .pixel_clock = 26000, - - .hfp = 104, - .hsw = 8, - .hbp = 8, - - .vfp = 4, - .vsw = 2, - .vbp = 2, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, - }, - .power_on_delay = 0, - .power_off_delay = 0, - .name = "toppoly_tdo35s", - }, - - /* Samsung LTE430WQ-F0C */ - { - { - .x_res = 480, - .y_res = 272, - - .pixel_clock = 9200, - - .hfp = 8, - .hsw = 41, - .hbp = 45 - 41, - - .vfp = 4, - .vsw = 10, - .vbp = 12 - 10, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .power_on_delay = 0, - .power_off_delay = 0, - .name = "samsung_lte430wq_f0c", - }, - - /* Seiko 70WVW1TZ3Z3 */ - { - { - .x_res = 800, - .y_res = 480, - - .pixel_clock = 33000, - - .hsw = 128, - .hfp = 10, - .hbp = 10, - - .vsw = 2, - .vfp = 4, - .vbp = 11, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .power_on_delay = 0, - .power_off_delay = 0, - .name = "seiko_70wvw1tz3", - }, - - /* Powertip PH480272T */ - { - { - .x_res = 480, - .y_res = 272, - - .pixel_clock = 9000, - - .hsw = 40, - .hfp = 2, - .hbp = 2, - - .vsw = 10, - .vfp = 2, - .vbp = 2, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_LOW, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .power_on_delay = 0, - .power_off_delay = 0, - .name = "powertip_ph480272t", - }, - - /* Innolux AT070TN83 */ - { - { - .x_res = 800, - .y_res = 480, - - .pixel_clock = 40000, - - .hsw = 48, - .hfp = 1, - .hbp = 1, - - .vsw = 3, - .vfp = 12, - .vbp = 25, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .power_on_delay = 0, - .power_off_delay = 0, - .name = "innolux_at070tn83", - }, - - /* NEC NL2432DR22-11B */ - { - { - .x_res = 240, - .y_res = 320, - - .pixel_clock = 5400, - - .hsw = 3, - .hfp = 3, - .hbp = 39, - - .vsw = 1, - .vfp = 2, - .vbp = 7, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "nec_nl2432dr22-11b", - }, - - /* Unknown panel used in OMAP H4 */ - { - { - .x_res = 240, - .y_res = 320, - - .pixel_clock = 6250, - - .hsw = 15, - .hfp = 15, - .hbp = 60, - - .vsw = 1, - .vfp = 1, - .vbp = 1, - - .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "h4", - }, - - /* FocalTech ETM070003DH6 */ - { - { - .x_res = 800, - .y_res = 480, - - .pixel_clock = 28000, - - .hsw = 48, - .hfp = 40, - .hbp = 40, - - .vsw = 3, - .vfp = 13, - .vbp = 29, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "focaltech_etm070003dh6", - }, - - /* Microtips Technologies - UMSH-8173MD */ - { - { - .x_res = 800, - .y_res = 480, - - .pixel_clock = 34560, - - .hsw = 13, - .hfp = 101, - .hbp = 101, - - .vsw = 23, - .vfp = 1, - .vbp = 1, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .power_on_delay = 0, - .power_off_delay = 0, - .name = "microtips_umsh_8173md", - }, - - /* OrtusTech COM43H4M10XTC */ - { - { - .x_res = 480, - .y_res = 272, - - .pixel_clock = 8000, - - .hsw = 41, - .hfp = 8, - .hbp = 4, - - .vsw = 10, - .vfp = 4, - .vbp = 2, - - .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "ortustech_com43h4m10xtc", - }, - - /* Innolux AT080TN52 */ - { - { - .x_res = 800, - .y_res = 600, - - .pixel_clock = 41142, - - .hsw = 20, - .hfp = 210, - .hbp = 46, - - .vsw = 10, - .vfp = 12, - .vbp = 23, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_LOW, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "innolux_at080tn52", - }, - - /* Mitsubishi AA084SB01 */ - { - { - .x_res = 800, - .y_res = 600, - .pixel_clock = 40000, - - .hsw = 1, - .hfp = 254, - .hbp = 1, - - .vsw = 1, - .vfp = 26, - .vbp = 1, - - .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "mitsubishi_aa084sb01", - }, - /* EDT ET0500G0DH6 */ - { - { - .x_res = 800, - .y_res = 480, - .pixel_clock = 33260, - - .hsw = 128, - .hfp = 216, - .hbp = 40, - - .vsw = 2, - .vfp = 35, - .vbp = 10, - - .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "edt_et0500g0dh6", - }, - - /* Prime-View PD050VL1 */ - { - { - .x_res = 640, - .y_res = 480, - - .pixel_clock = 25000, - - .hsw = 96, - .hfp = 18, - .hbp = 46, - - .vsw = 2, - .vfp = 10, - .vbp = 33, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "primeview_pd050vl1", - }, - - /* Prime-View PM070WL4 */ - { - { - .x_res = 800, - .y_res = 480, - - .pixel_clock = 32000, - - .hsw = 128, - .hfp = 42, - .hbp = 86, - - .vsw = 2, - .vfp = 10, - .vbp = 33, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "primeview_pm070wl4", - }, - - /* Prime-View PD104SLF */ - { - { - .x_res = 800, - .y_res = 600, - - .pixel_clock = 40000, - - .hsw = 128, - .hfp = 42, - .hbp = 86, - - .vsw = 4, - .vfp = 1, - .vbp = 23, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, - }, - .name = "primeview_pd104slf", - }, -}; - -struct panel_drv_data { - - struct omap_dss_device *dssdev; - - struct panel_config *panel_config; - - struct mutex lock; -}; - -static inline struct panel_generic_dpi_data -*get_panel_data(const struct omap_dss_device *dssdev) -{ - return (struct panel_generic_dpi_data *) dssdev->data; -} - -static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev) -{ - int r, i; - struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); - struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); - struct panel_config *panel_config = drv_data->panel_config; - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); - - r = omapdss_dpi_display_enable(dssdev); - if (r) - goto err0; - - /* wait couple of vsyncs until enabling the LCD */ - if (panel_config->power_on_delay) - msleep(panel_config->power_on_delay); - - for (i = 0; i < panel_data->num_gpios; ++i) { - gpio_set_value_cansleep(panel_data->gpios[i], - panel_data->gpio_invert[i] ? 0 : 1); - } - - return 0; - -err0: - return r; -} - -static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev) -{ - struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); - struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); - struct panel_config *panel_config = drv_data->panel_config; - int i; - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - for (i = panel_data->num_gpios - 1; i >= 0; --i) { - gpio_set_value_cansleep(panel_data->gpios[i], - panel_data->gpio_invert[i] ? 1 : 0); - } - - /* wait couple of vsyncs after disabling the LCD */ - if (panel_config->power_off_delay) - msleep(panel_config->power_off_delay); - - omapdss_dpi_display_disable(dssdev); -} - -static int generic_dpi_panel_probe(struct omap_dss_device *dssdev) -{ - struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); - struct panel_config *panel_config = NULL; - struct panel_drv_data *drv_data = NULL; - int i, r; - - dev_dbg(dssdev->dev, "probe\n"); - - if (!panel_data || !panel_data->name) - return -EINVAL; - - for (i = 0; i < ARRAY_SIZE(generic_dpi_panels); i++) { - if (strcmp(panel_data->name, generic_dpi_panels[i].name) == 0) { - panel_config = &generic_dpi_panels[i]; - break; - } - } - - if (!panel_config) - return -EINVAL; - - for (i = 0; i < panel_data->num_gpios; ++i) { - r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i], - panel_data->gpio_invert[i] ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, - "panel gpio"); - if (r) - return r; - } - - dssdev->panel.timings = panel_config->timings; - - drv_data = devm_kzalloc(dssdev->dev, sizeof(*drv_data), GFP_KERNEL); - if (!drv_data) - return -ENOMEM; - - drv_data->dssdev = dssdev; - drv_data->panel_config = panel_config; - - mutex_init(&drv_data->lock); - - dev_set_drvdata(dssdev->dev, drv_data); - - return 0; -} - -static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev) -{ - dev_dbg(dssdev->dev, "remove\n"); - - dev_set_drvdata(dssdev->dev, NULL); -} - -static int generic_dpi_panel_enable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); - int r; - - mutex_lock(&drv_data->lock); - - r = generic_dpi_panel_power_on(dssdev); - if (r) - goto err; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -err: - mutex_unlock(&drv_data->lock); - - return r; -} - -static void generic_dpi_panel_disable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); - - mutex_lock(&drv_data->lock); - - generic_dpi_panel_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - - mutex_unlock(&drv_data->lock); -} - -static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); - - mutex_lock(&drv_data->lock); - - omapdss_dpi_set_timings(dssdev, timings); - - dssdev->panel.timings = *timings; - - mutex_unlock(&drv_data->lock); -} - -static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); - - mutex_lock(&drv_data->lock); - - *timings = dssdev->panel.timings; - - mutex_unlock(&drv_data->lock); -} - -static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - struct panel_drv_data *drv_data = dev_get_drvdata(dssdev->dev); - int r; - - mutex_lock(&drv_data->lock); - - r = dpi_check_timings(dssdev, timings); - - mutex_unlock(&drv_data->lock); - - return r; -} - -static struct omap_dss_driver dpi_driver = { - .probe = generic_dpi_panel_probe, - .remove = __exit_p(generic_dpi_panel_remove), - - .enable = generic_dpi_panel_enable, - .disable = generic_dpi_panel_disable, - - .set_timings = generic_dpi_panel_set_timings, - .get_timings = generic_dpi_panel_get_timings, - .check_timings = generic_dpi_panel_check_timings, - - .driver = { - .name = "generic_dpi_panel", - .owner = THIS_MODULE, - }, -}; - -static int __init generic_dpi_panel_drv_init(void) -{ - return omap_dss_register_driver(&dpi_driver); -} - -static void __exit generic_dpi_panel_drv_exit(void) -{ - omap_dss_unregister_driver(&dpi_driver); -} - -module_init(generic_dpi_panel_drv_init); -module_exit(generic_dpi_panel_drv_exit); -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 @@ -/* - * LCD panel driver for LG.Philips LB035Q02 - * - * Author: Steve Sakoman <steve@sakoman.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/mutex.h> -#include <linux/gpio.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -struct lb035q02_data { - struct mutex lock; -}; - -static struct omap_video_timings lb035q02_timings = { - .x_res = 320, - .y_res = 240, - - .pixel_clock = 6500, - - .hsw = 2, - .hfp = 20, - .hbp = 68, - - .vsw = 2, - .vfp = 4, - .vbp = 18, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, -}; - -static inline struct panel_generic_dpi_data -*get_panel_data(const struct omap_dss_device *dssdev) -{ - return (struct panel_generic_dpi_data *) dssdev->data; -} - -static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) -{ - struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); - int r, i; - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); - - r = omapdss_dpi_display_enable(dssdev); - if (r) - goto err0; - - for (i = 0; i < panel_data->num_gpios; ++i) { - gpio_set_value_cansleep(panel_data->gpios[i], - panel_data->gpio_invert[i] ? 0 : 1); - } - - return 0; - -err0: - return r; -} - -static void lb035q02_panel_power_off(struct omap_dss_device *dssdev) -{ - struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); - int i; - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - for (i = panel_data->num_gpios - 1; i >= 0; --i) { - gpio_set_value_cansleep(panel_data->gpios[i], - panel_data->gpio_invert[i] ? 1 : 0); - } - - omapdss_dpi_display_disable(dssdev); -} - -static int lb035q02_panel_probe(struct omap_dss_device *dssdev) -{ - struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); - struct lb035q02_data *ld; - int r, i; - - if (!panel_data) - return -EINVAL; - - dssdev->panel.timings = lb035q02_timings; - - ld = devm_kzalloc(dssdev->dev, sizeof(*ld), GFP_KERNEL); - if (!ld) - return -ENOMEM; - - for (i = 0; i < panel_data->num_gpios; ++i) { - r = devm_gpio_request_one(dssdev->dev, panel_data->gpios[i], - panel_data->gpio_invert[i] ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, - "panel gpio"); - if (r) - return r; - } - - mutex_init(&ld->lock); - dev_set_drvdata(dssdev->dev, ld); - - return 0; -} - -static void lb035q02_panel_remove(struct omap_dss_device *dssdev) -{ -} - -static int lb035q02_panel_enable(struct omap_dss_device *dssdev) -{ - struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev); - int r; - - mutex_lock(&ld->lock); - - r = lb035q02_panel_power_on(dssdev); - if (r) - goto err; - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - mutex_unlock(&ld->lock); - return 0; -err: - mutex_unlock(&ld->lock); - return r; -} - -static void lb035q02_panel_disable(struct omap_dss_device *dssdev) -{ - struct lb035q02_data *ld = dev_get_drvdata(dssdev->dev); - - mutex_lock(&ld->lock); - - lb035q02_panel_power_off(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - - mutex_unlock(&ld->lock); -} - -static struct omap_dss_driver lb035q02_driver = { - .probe = lb035q02_panel_probe, - .remove = lb035q02_panel_remove, - - .enable = lb035q02_panel_enable, - .disable = lb035q02_panel_disable, - - .driver = { - .name = "lgphilips_lb035q02_panel", - .owner = THIS_MODULE, - }, -}; - -static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val) -{ - struct spi_message msg; - struct spi_transfer index_xfer = { - .len = 3, - .cs_change = 1, - }; - struct spi_transfer value_xfer = { - .len = 3, - }; - u8 buffer[16]; - - spi_message_init(&msg); - - /* register index */ - buffer[0] = 0x70; - buffer[1] = 0x00; - buffer[2] = reg & 0x7f; - index_xfer.tx_buf = buffer; - spi_message_add_tail(&index_xfer, &msg); - - /* register value */ - buffer[4] = 0x72; - buffer[5] = val >> 8; - buffer[6] = val; - value_xfer.tx_buf = buffer + 4; - spi_message_add_tail(&value_xfer, &msg); - - return spi_sync(spi, &msg); -} - -static void init_lb035q02_panel(struct spi_device *spi) -{ - /* Init sequence from page 28 of the lb035q02 spec */ - lb035q02_write_reg(spi, 0x01, 0x6300); - lb035q02_write_reg(spi, 0x02, 0x0200); - lb035q02_write_reg(spi, 0x03, 0x0177); - lb035q02_write_reg(spi, 0x04, 0x04c7); - lb035q02_write_reg(spi, 0x05, 0xffc0); - lb035q02_write_reg(spi, 0x06, 0xe806); - lb035q02_write_reg(spi, 0x0a, 0x4008); - lb035q02_write_reg(spi, 0x0b, 0x0000); - lb035q02_write_reg(spi, 0x0d, 0x0030); - lb035q02_write_reg(spi, 0x0e, 0x2800); - lb035q02_write_reg(spi, 0x0f, 0x0000); - lb035q02_write_reg(spi, 0x16, 0x9f80); - lb035q02_write_reg(spi, 0x17, 0x0a0f); - lb035q02_write_reg(spi, 0x1e, 0x00c1); - lb035q02_write_reg(spi, 0x30, 0x0300); - lb035q02_write_reg(spi, 0x31, 0x0007); - lb035q02_write_reg(spi, 0x32, 0x0000); - lb035q02_write_reg(spi, 0x33, 0x0000); - lb035q02_write_reg(spi, 0x34, 0x0707); - lb035q02_write_reg(spi, 0x35, 0x0004); - lb035q02_write_reg(spi, 0x36, 0x0302); - lb035q02_write_reg(spi, 0x37, 0x0202); - lb035q02_write_reg(spi, 0x3a, 0x0a0d); - lb035q02_write_reg(spi, 0x3b, 0x0806); -} - -static int lb035q02_panel_spi_probe(struct spi_device *spi) -{ - init_lb035q02_panel(spi); - return omap_dss_register_driver(&lb035q02_driver); -} - -static int lb035q02_panel_spi_remove(struct spi_device *spi) -{ - omap_dss_unregister_driver(&lb035q02_driver); - return 0; -} - -static struct spi_driver lb035q02_spi_driver = { - .driver = { - .name = "lgphilips_lb035q02_panel-spi", - .owner = THIS_MODULE, - }, - .probe = lb035q02_panel_spi_probe, - .remove = lb035q02_panel_spi_remove, -}; - -module_spi_driver(lb035q02_spi_driver); - -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 @@ -/* #define DEBUG */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/gpio.h> -#include <linux/spi/spi.h> -#include <linux/fb.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#define BLIZZARD_REV_CODE 0x00 -#define BLIZZARD_CONFIG 0x02 -#define BLIZZARD_PLL_DIV 0x04 -#define BLIZZARD_PLL_LOCK_RANGE 0x06 -#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08 -#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a -#define BLIZZARD_PLL_MODE 0x0c -#define BLIZZARD_CLK_SRC 0x0e -#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10 -#define BLIZZARD_MEM_BANK0_STATUS 0x14 -#define BLIZZARD_PANEL_CONFIGURATION 0x28 -#define BLIZZARD_HDISP 0x2a -#define BLIZZARD_HNDP 0x2c -#define BLIZZARD_VDISP0 0x2e -#define BLIZZARD_VDISP1 0x30 -#define BLIZZARD_VNDP 0x32 -#define BLIZZARD_HSW 0x34 -#define BLIZZARD_VSW 0x38 -#define BLIZZARD_DISPLAY_MODE 0x68 -#define BLIZZARD_INPUT_WIN_X_START_0 0x6c -#define BLIZZARD_DATA_SOURCE_SELECT 0x8e -#define BLIZZARD_DISP_MEM_DATA_PORT 0x90 -#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92 -#define BLIZZARD_POWER_SAVE 0xE6 -#define BLIZZARD_NDISP_CTRL_STATUS 0xE8 - -/* Data source select */ -/* For S1D13745 */ -#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00 -#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01 -#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04 -#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05 -/* For S1D13744 */ -#define BLIZZARD_SRC_WRITE_LCD 0x00 -#define BLIZZARD_SRC_BLT_LCD 0x06 - -#define BLIZZARD_COLOR_RGB565 0x01 -#define BLIZZARD_COLOR_YUV420 0x09 - -#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */ -#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */ - -#define MIPID_CMD_READ_DISP_ID 0x04 -#define MIPID_CMD_READ_RED 0x06 -#define MIPID_CMD_READ_GREEN 0x07 -#define MIPID_CMD_READ_BLUE 0x08 -#define MIPID_CMD_READ_DISP_STATUS 0x09 -#define MIPID_CMD_RDDSDR 0x0F -#define MIPID_CMD_SLEEP_IN 0x10 -#define MIPID_CMD_SLEEP_OUT 0x11 -#define MIPID_CMD_DISP_OFF 0x28 -#define MIPID_CMD_DISP_ON 0x29 - -static struct panel_drv_data { - struct mutex lock; - - struct omap_dss_device *dssdev; - struct spi_device *spidev; - - int blizzard_ver; -} s_drv_data; - - -static inline -struct panel_n8x0_data *get_board_data(const struct omap_dss_device *dssdev) -{ - return dssdev->data; -} - -static inline -struct panel_drv_data *get_drv_data(const struct omap_dss_device *dssdev) -{ - return &s_drv_data; -} - - -static inline void blizzard_cmd(u8 cmd) -{ - omap_rfbi_write_command(&cmd, 1); -} - -static inline void blizzard_write(u8 cmd, const u8 *buf, int len) -{ - omap_rfbi_write_command(&cmd, 1); - omap_rfbi_write_data(buf, len); -} - -static inline void blizzard_read(u8 cmd, u8 *buf, int len) -{ - omap_rfbi_write_command(&cmd, 1); - omap_rfbi_read_data(buf, len); -} - -static u8 blizzard_read_reg(u8 cmd) -{ - u8 data; - blizzard_read(cmd, &data, 1); - return data; -} - -static void blizzard_ctrl_setup_update(struct omap_dss_device *dssdev, - int x, int y, int w, int h) -{ - struct panel_drv_data *ddata = get_drv_data(dssdev); - u8 tmp[18]; - int x_end, y_end; - - x_end = x + w - 1; - y_end = y + h - 1; - - tmp[0] = x; - tmp[1] = x >> 8; - tmp[2] = y; - tmp[3] = y >> 8; - tmp[4] = x_end; - tmp[5] = x_end >> 8; - tmp[6] = y_end; - tmp[7] = y_end >> 8; - - /* scaling? */ - tmp[8] = x; - tmp[9] = x >> 8; - tmp[10] = y; - tmp[11] = y >> 8; - tmp[12] = x_end; - tmp[13] = x_end >> 8; - tmp[14] = y_end; - tmp[15] = y_end >> 8; - - tmp[16] = BLIZZARD_COLOR_RGB565; - - if (ddata->blizzard_ver == BLIZZARD_VERSION_S1D13745) - tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND; - else - tmp[17] = ddata->blizzard_ver == BLIZZARD_VERSION_S1D13744 ? - BLIZZARD_SRC_WRITE_LCD : - BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE; - - omapdss_rfbi_set_pixel_size(dssdev, 16); - omapdss_rfbi_set_data_lines(dssdev, 8); - - omap_rfbi_configure(dssdev); - - blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18); - - omapdss_rfbi_set_pixel_size(dssdev, 16); - omapdss_rfbi_set_data_lines(dssdev, 16); - - omap_rfbi_configure(dssdev); -} - -static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf, - int wlen, u8 *rbuf, int rlen) -{ - struct spi_message m; - struct spi_transfer *x, xfer[4]; - u16 w; - int r; - - spi_message_init(&m); - - memset(xfer, 0, sizeof(xfer)); - x = &xfer[0]; - - cmd &= 0xff; - x->tx_buf = &cmd; - x->bits_per_word = 9; - x->len = 2; - spi_message_add_tail(x, &m); - - if (wlen) { - x++; - x->tx_buf = wbuf; - x->len = wlen; - x->bits_per_word = 9; - spi_message_add_tail(x, &m); - } - - if (rlen) { - x++; - x->rx_buf = &w; - x->len = 1; - spi_message_add_tail(x, &m); - - if (rlen > 1) { - /* Arrange for the extra clock before the first - * data bit. - */ - x->bits_per_word = 9; - x->len = 2; - - x++; - x->rx_buf = &rbuf[1]; - x->len = rlen - 1; - spi_message_add_tail(x, &m); - } - } - - r = spi_sync(spi, &m); - if (r < 0) - dev_dbg(&spi->dev, "spi_sync %d\n", r); - - if (rlen) - rbuf[0] = w & 0xff; -} - -static inline void mipid_cmd(struct spi_device *spi, int cmd) -{ - mipid_transfer(spi, cmd, NULL, 0, NULL, 0); -} - -static inline void mipid_write(struct spi_device *spi, - int reg, const u8 *buf, int len) -{ - mipid_transfer(spi, reg, buf, len, NULL, 0); -} - -static inline void mipid_read(struct spi_device *spi, - int reg, u8 *buf, int len) -{ - mipid_transfer(spi, reg, NULL, 0, buf, len); -} - -static void set_data_lines(struct spi_device *spi, int data_lines) -{ - u16 par; - - switch (data_lines) { - case 16: - par = 0x150; - break; - case 18: - par = 0x160; - break; - case 24: - par = 0x170; - break; - } - - mipid_write(spi, 0x3a, (u8 *)&par, 2); -} - -static void send_init_string(struct spi_device *spi) -{ - u16 initpar[] = { 0x0102, 0x0100, 0x0100 }; - mipid_write(spi, 0xc2, (u8 *)initpar, sizeof(initpar)); -} - -static void send_display_on(struct spi_device *spi) -{ - mipid_cmd(spi, MIPID_CMD_DISP_ON); -} - -static void send_display_off(struct spi_device *spi) -{ - mipid_cmd(spi, MIPID_CMD_DISP_OFF); -} - -static void send_sleep_out(struct spi_device *spi) -{ - mipid_cmd(spi, MIPID_CMD_SLEEP_OUT); - msleep(120); -} - -static void send_sleep_in(struct spi_device *spi) -{ - mipid_cmd(spi, MIPID_CMD_SLEEP_IN); - msleep(50); -} - -static int n8x0_panel_power_on(struct omap_dss_device *dssdev) -{ - int r; - struct panel_n8x0_data *bdata = get_board_data(dssdev); - struct panel_drv_data *ddata = get_drv_data(dssdev); - struct spi_device *spi = ddata->spidev; - u8 rev, conf; - u8 display_id[3]; - const char *panel_name; - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - gpio_direction_output(bdata->ctrl_pwrdown, 1); - - omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res, - dssdev->panel.timings.y_res); - omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size); - omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines); - omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings); - - r = omapdss_rfbi_display_enable(dssdev); - if (r) - goto err_rfbi_en; - - rev = blizzard_read_reg(BLIZZARD_REV_CODE); - conf = blizzard_read_reg(BLIZZARD_CONFIG); - - switch (rev & 0xfc) { - case 0x9c: - ddata->blizzard_ver = BLIZZARD_VERSION_S1D13744; - dev_info(dssdev->dev, "s1d13744 LCD controller rev %d " - "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); - break; - case 0xa4: - ddata->blizzard_ver = BLIZZARD_VERSION_S1D13745; - dev_info(dssdev->dev, "s1d13745 LCD controller rev %d " - "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07); - break; - default: - dev_err(dssdev->dev, "invalid s1d1374x revision %02x\n", rev); - r = -ENODEV; - goto err_inv_chip; - } - - /* panel */ - - gpio_direction_output(bdata->panel_reset, 1); - - mipid_read(spi, MIPID_CMD_READ_DISP_ID, display_id, 3); - dev_dbg(&spi->dev, "MIPI display ID: %02x%02x%02x\n", - display_id[0], display_id[1], display_id[2]); - - switch (display_id[0]) { - case 0x45: - panel_name = "lph8923"; - break; - case 0x83: - panel_name = "ls041y3"; - break; - default: - dev_err(dssdev->dev, "invalid display ID 0x%x\n", - display_id[0]); - r = -ENODEV; - goto err_inv_panel; - } - - dev_info(dssdev->dev, "%s rev %02x LCD detected\n", - panel_name, display_id[1]); - - send_sleep_out(spi); - send_init_string(spi); - set_data_lines(spi, 24); - send_display_on(spi); - - return 0; - -err_inv_panel: - /* - * HACK: we should turn off the panel here, but there is some problem - * with the initialization sequence, and we fail to init the panel if we - * have turned it off - */ - /* gpio_direction_output(bdata->panel_reset, 0); */ -err_inv_chip: - omapdss_rfbi_display_disable(dssdev); -err_rfbi_en: - gpio_direction_output(bdata->ctrl_pwrdown, 0); - return r; -} - -static void n8x0_panel_power_off(struct omap_dss_device *dssdev) -{ - struct panel_n8x0_data *bdata = get_board_data(dssdev); - struct panel_drv_data *ddata = get_drv_data(dssdev); - struct spi_device *spi = ddata->spidev; - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - send_display_off(spi); - send_sleep_in(spi); - - /* - * HACK: we should turn off the panel here, but there is some problem - * with the initialization sequence, and we fail to init the panel if we - * have turned it off - */ - /* gpio_direction_output(bdata->panel_reset, 0); */ - gpio_direction_output(bdata->ctrl_pwrdown, 0); - omapdss_rfbi_display_disable(dssdev); -} - -static const struct rfbi_timings n8x0_panel_timings = { - .cs_on_time = 0, - - .we_on_time = 9000, - .we_off_time = 18000, - .we_cycle_time = 36000, - - .re_on_time = 9000, - .re_off_time = 27000, - .re_cycle_time = 36000, - - .access_time = 27000, - .cs_off_time = 36000, - - .cs_pulse_width = 0, -}; - -static int n8x0_panel_probe(struct omap_dss_device *dssdev) -{ - struct panel_n8x0_data *bdata = get_board_data(dssdev); - struct panel_drv_data *ddata; - int r; - - dev_dbg(dssdev->dev, "probe\n"); - - if (!bdata) - return -EINVAL; - - s_drv_data.dssdev = dssdev; - - ddata = &s_drv_data; - - mutex_init(&ddata->lock); - - dssdev->panel.timings.x_res = 800; - dssdev->panel.timings.y_res = 480; - dssdev->ctrl.pixel_size = 16; - dssdev->ctrl.rfbi_timings = n8x0_panel_timings; - dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; - - if (gpio_is_valid(bdata->panel_reset)) { - r = devm_gpio_request_one(dssdev->dev, bdata->panel_reset, - GPIOF_OUT_INIT_LOW, "PANEL RESET"); - if (r) - return r; - } - - if (gpio_is_valid(bdata->ctrl_pwrdown)) { - r = devm_gpio_request_one(dssdev->dev, bdata->ctrl_pwrdown, - GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN"); - if (r) - return r; - } - - return 0; -} - -static void n8x0_panel_remove(struct omap_dss_device *dssdev) -{ - dev_dbg(dssdev->dev, "remove\n"); - - dev_set_drvdata(dssdev->dev, NULL); -} - -static int n8x0_panel_enable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = get_drv_data(dssdev); - int r; - - dev_dbg(dssdev->dev, "enable\n"); - - mutex_lock(&ddata->lock); - - rfbi_bus_lock(); - - r = n8x0_panel_power_on(dssdev); - - rfbi_bus_unlock(); - - if (r) { - mutex_unlock(&ddata->lock); - return r; - } - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - mutex_unlock(&ddata->lock); - - return 0; -} - -static void n8x0_panel_disable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = get_drv_data(dssdev); - - dev_dbg(dssdev->dev, "disable\n"); - - mutex_lock(&ddata->lock); - - rfbi_bus_lock(); - - n8x0_panel_power_off(dssdev); - - rfbi_bus_unlock(); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - - mutex_unlock(&ddata->lock); -} - -static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, - u16 *xres, u16 *yres) -{ - *xres = dssdev->panel.timings.x_res; - *yres = dssdev->panel.timings.y_res; -} - -static void update_done(void *data) -{ - rfbi_bus_unlock(); -} - -static int n8x0_panel_update(struct omap_dss_device *dssdev, - u16 x, u16 y, u16 w, u16 h) -{ - struct panel_drv_data *ddata = get_drv_data(dssdev); - u16 dw, dh; - - dev_dbg(dssdev->dev, "update\n"); - - dw = dssdev->panel.timings.x_res; - dh = dssdev->panel.timings.y_res; - - if (x != 0 || y != 0 || w != dw || h != dh) { - dev_err(dssdev->dev, "invalid update region %d, %d, %d, %d\n", - x, y, w, h); - return -EINVAL; - } - - mutex_lock(&ddata->lock); - rfbi_bus_lock(); - - blizzard_ctrl_setup_update(dssdev, x, y, w, h); - - omap_rfbi_update(dssdev, update_done, NULL); - - mutex_unlock(&ddata->lock); - - return 0; -} - -static int n8x0_panel_sync(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = get_drv_data(dssdev); - - dev_dbg(dssdev->dev, "sync\n"); - - mutex_lock(&ddata->lock); - rfbi_bus_lock(); - rfbi_bus_unlock(); - mutex_unlock(&ddata->lock); - - return 0; -} - -static struct omap_dss_driver n8x0_panel_driver = { - .probe = n8x0_panel_probe, - .remove = n8x0_panel_remove, - - .enable = n8x0_panel_enable, - .disable = n8x0_panel_disable, - - .update = n8x0_panel_update, - .sync = n8x0_panel_sync, - - .get_resolution = n8x0_panel_get_resolution, - .get_recommended_bpp = omapdss_default_get_recommended_bpp, - - .driver = { - .name = "n8x0_panel", - .owner = THIS_MODULE, - }, -}; - -/* PANEL */ - -static int mipid_spi_probe(struct spi_device *spi) -{ - int r; - - dev_dbg(&spi->dev, "mipid_spi_probe\n"); - - spi->mode = SPI_MODE_0; - - s_drv_data.spidev = spi; - - r = omap_dss_register_driver(&n8x0_panel_driver); - if (r) - pr_err("n8x0_panel: dss driver registration failed\n"); - - return r; -} - -static int mipid_spi_remove(struct spi_device *spi) -{ - dev_dbg(&spi->dev, "mipid_spi_remove\n"); - omap_dss_unregister_driver(&n8x0_panel_driver); - return 0; -} - -static struct spi_driver mipid_spi_driver = { - .driver = { - .name = "lcd_mipid", - .owner = THIS_MODULE, - }, - .probe = mipid_spi_probe, - .remove = mipid_spi_remove, -}; -module_spi_driver(mipid_spi_driver); - -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 @@ -/* - * Support for NEC-nl8048hl11-01b panel driver - * - * Copyright (C) 2010 Texas Instruments Inc. - * Author: Erik Gilling <konkers@android.com> - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/fb.h> -#include <linux/gpio.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#define LCD_XRES 800 -#define LCD_YRES 480 -/* - * NEC PIX Clock Ratings - * MIN:21.8MHz TYP:23.8MHz MAX:25.7MHz - */ -#define LCD_PIXEL_CLOCK 23800 - -static const struct { - unsigned char addr; - unsigned char dat; -} nec_8048_init_seq[] = { - { 3, 0x01 }, { 0, 0x00 }, { 1, 0x01 }, { 4, 0x00 }, { 5, 0x14 }, - { 6, 0x24 }, { 16, 0xD7 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x55 }, - { 20, 0x01 }, { 21, 0x70 }, { 22, 0x1E }, { 23, 0x25 }, { 24, 0x25 }, - { 25, 0x02 }, { 26, 0x02 }, { 27, 0xA0 }, { 32, 0x2F }, { 33, 0x0F }, - { 34, 0x0F }, { 35, 0x0F }, { 36, 0x0F }, { 37, 0x0F }, { 38, 0x0F }, - { 39, 0x00 }, { 40, 0x02 }, { 41, 0x02 }, { 42, 0x02 }, { 43, 0x0F }, - { 44, 0x0F }, { 45, 0x0F }, { 46, 0x0F }, { 47, 0x0F }, { 48, 0x0F }, - { 49, 0x0F }, { 50, 0x00 }, { 51, 0x02 }, { 52, 0x02 }, { 53, 0x02 }, - { 80, 0x0C }, { 83, 0x42 }, { 84, 0x42 }, { 85, 0x41 }, { 86, 0x14 }, - { 89, 0x88 }, { 90, 0x01 }, { 91, 0x00 }, { 92, 0x02 }, { 93, 0x0C }, - { 94, 0x1C }, { 95, 0x27 }, { 98, 0x49 }, { 99, 0x27 }, { 102, 0x76 }, - { 103, 0x27 }, { 112, 0x01 }, { 113, 0x0E }, { 114, 0x02 }, - { 115, 0x0C }, { 118, 0x0C }, { 121, 0x30 }, { 130, 0x00 }, - { 131, 0x00 }, { 132, 0xFC }, { 134, 0x00 }, { 136, 0x00 }, - { 138, 0x00 }, { 139, 0x00 }, { 140, 0x00 }, { 141, 0xFC }, - { 143, 0x00 }, { 145, 0x00 }, { 147, 0x00 }, { 148, 0x00 }, - { 149, 0x00 }, { 150, 0xFC }, { 152, 0x00 }, { 154, 0x00 }, - { 156, 0x00 }, { 157, 0x00 }, { 2, 0x00 }, -}; - -/* - * NEC NL8048HL11-01B Manual - * defines HFB, HSW, HBP, VFP, VSW, VBP as shown below - */ - -static struct omap_video_timings nec_8048_panel_timings = { - /* 800 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ - .x_res = LCD_XRES, - .y_res = LCD_YRES, - .pixel_clock = LCD_PIXEL_CLOCK, - .hfp = 6, - .hsw = 1, - .hbp = 4, - .vfp = 3, - .vsw = 1, - .vbp = 4, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, -}; - -static inline struct panel_nec_nl8048_data -*get_panel_data(const struct omap_dss_device *dssdev) -{ - return (struct panel_nec_nl8048_data *) dssdev->data; -} - -static int nec_8048_panel_probe(struct omap_dss_device *dssdev) -{ - struct panel_nec_nl8048_data *pd = get_panel_data(dssdev); - int r; - - if (!pd) - return -EINVAL; - - dssdev->panel.timings = nec_8048_panel_timings; - - if (gpio_is_valid(pd->qvga_gpio)) { - r = devm_gpio_request_one(dssdev->dev, pd->qvga_gpio, - GPIOF_OUT_INIT_HIGH, "lcd QVGA"); - if (r) - return r; - } - - if (gpio_is_valid(pd->res_gpio)) { - r = devm_gpio_request_one(dssdev->dev, pd->res_gpio, - GPIOF_OUT_INIT_LOW, "lcd RES"); - if (r) - return r; - } - - return 0; -} - -static void nec_8048_panel_remove(struct omap_dss_device *dssdev) -{ -} - -static int nec_8048_panel_power_on(struct omap_dss_device *dssdev) -{ - struct panel_nec_nl8048_data *pd = get_panel_data(dssdev); - int r; - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); - - r = omapdss_dpi_display_enable(dssdev); - if (r) - goto err0; - - if (gpio_is_valid(pd->res_gpio)) - gpio_set_value_cansleep(pd->res_gpio, 1); - - return 0; - -err0: - return r; -} - -static void nec_8048_panel_power_off(struct omap_dss_device *dssdev) -{ - struct panel_nec_nl8048_data *pd = get_panel_data(dssdev); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - if (gpio_is_valid(pd->res_gpio)) - gpio_set_value_cansleep(pd->res_gpio, 0); - - omapdss_dpi_display_disable(dssdev); -} - -static int nec_8048_panel_enable(struct omap_dss_device *dssdev) -{ - int r; - - r = nec_8048_panel_power_on(dssdev); - if (r) - return r; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - return 0; -} - -static void nec_8048_panel_disable(struct omap_dss_device *dssdev) -{ - nec_8048_panel_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -} - -static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev) -{ - return 16; -} - -static struct omap_dss_driver nec_8048_driver = { - .probe = nec_8048_panel_probe, - .remove = nec_8048_panel_remove, - .enable = nec_8048_panel_enable, - .disable = nec_8048_panel_disable, - .get_recommended_bpp = nec_8048_recommended_bpp, - - .driver = { - .name = "NEC_8048_panel", - .owner = THIS_MODULE, - }, -}; - -static int nec_8048_spi_send(struct spi_device *spi, unsigned char reg_addr, - unsigned char reg_data) -{ - int ret = 0; - unsigned int cmd = 0, data = 0; - - cmd = 0x0000 | reg_addr; /* register address write */ - data = 0x0100 | reg_data ; /* register data write */ - data = (cmd << 16) | data; - - ret = spi_write(spi, (unsigned char *)&data, 4); - if (ret) - pr_err("error in spi_write %x\n", data); - - return ret; -} - -static int init_nec_8048_wvga_lcd(struct spi_device *spi) -{ - unsigned int i; - /* Initialization Sequence */ - /* nec_8048_spi_send(spi, REG, VAL) */ - for (i = 0; i < (ARRAY_SIZE(nec_8048_init_seq) - 1); i++) - nec_8048_spi_send(spi, nec_8048_init_seq[i].addr, - nec_8048_init_seq[i].dat); - udelay(20); - nec_8048_spi_send(spi, nec_8048_init_seq[i].addr, - nec_8048_init_seq[i].dat); - return 0; -} - -static int nec_8048_spi_probe(struct spi_device *spi) -{ - spi->mode = SPI_MODE_0; - spi->bits_per_word = 32; - spi_setup(spi); - - init_nec_8048_wvga_lcd(spi); - - return omap_dss_register_driver(&nec_8048_driver); -} - -static int nec_8048_spi_remove(struct spi_device *spi) -{ - omap_dss_unregister_driver(&nec_8048_driver); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP - -static int nec_8048_spi_suspend(struct device *dev) -{ - struct spi_device *spi = to_spi_device(dev); - - nec_8048_spi_send(spi, 2, 0x01); - mdelay(40); - - return 0; -} - -static int nec_8048_spi_resume(struct device *dev) -{ - struct spi_device *spi = to_spi_device(dev); - - /* reinitialize the panel */ - spi_setup(spi); - nec_8048_spi_send(spi, 2, 0x00); - init_nec_8048_wvga_lcd(spi); - - return 0; -} - -static SIMPLE_DEV_PM_OPS(nec_8048_spi_pm_ops, nec_8048_spi_suspend, - nec_8048_spi_resume); -#define NEC_8048_SPI_PM_OPS (&nec_8048_spi_pm_ops) -#else -#define NEC_8048_SPI_PM_OPS NULL -#endif - -static struct spi_driver nec_8048_spi_driver = { - .probe = nec_8048_spi_probe, - .remove = nec_8048_spi_remove, - .driver = { - .name = "nec_8048_spi", - .owner = THIS_MODULE, - .pm = NEC_8048_SPI_PM_OPS, - }, -}; - -module_spi_driver(nec_8048_spi_driver); - -MODULE_AUTHOR("Erik Gilling <konkers@android.com>"); -MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver"); -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 @@ -/* - * picodlp panel driver - * picodlp_i2c_driver: i2c_client driver - * - * Copyright (C) 2009-2011 Texas Instruments - * Author: Mythri P K <mythripk@ti.com> - * Mayuresh Janorkar <mayur@ti.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/input.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/i2c.h> -#include <linux/delay.h> -#include <linux/gpio.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#include "panel-picodlp.h" - -struct picodlp_data { - struct mutex lock; - struct i2c_client *picodlp_i2c_client; -}; - -static struct i2c_board_info picodlp_i2c_board_info = { - I2C_BOARD_INFO("picodlp_i2c_driver", 0x1b), -}; - -struct picodlp_i2c_data { - struct mutex xfer_lock; -}; - -static struct i2c_device_id picodlp_i2c_id[] = { - { "picodlp_i2c_driver", 0 }, - { } -}; - -struct picodlp_i2c_command { - u8 reg; - u32 value; -}; - -static struct omap_video_timings pico_ls_timings = { - .x_res = 864, - .y_res = 480, - .hsw = 7, - .hfp = 11, - .hbp = 7, - - .pixel_clock = 19200, - - .vsw = 2, - .vfp = 3, - .vbp = 14, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, -}; - -static inline struct picodlp_panel_data - *get_panel_data(const struct omap_dss_device *dssdev) -{ - return (struct picodlp_panel_data *) dssdev->data; -} - -static u32 picodlp_i2c_read(struct i2c_client *client, u8 reg) -{ - u8 read_cmd[] = {READ_REG_SELECT, reg}, data[4]; - struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client); - struct i2c_msg msg[2]; - - mutex_lock(&picodlp_i2c_data->xfer_lock); - - msg[0].addr = client->addr; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = read_cmd; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = 4; - msg[1].buf = data; - - i2c_transfer(client->adapter, msg, 2); - mutex_unlock(&picodlp_i2c_data->xfer_lock); - return (data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24)); -} - -static int picodlp_i2c_write_block(struct i2c_client *client, - u8 *data, int len) -{ - struct i2c_msg msg; - int i, r, msg_count = 1; - - struct picodlp_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client); - - if (len < 1 || len > 32) { - dev_err(&client->dev, - "too long syn_write_block len %d\n", len); - return -EIO; - } - mutex_lock(&picodlp_i2c_data->xfer_lock); - - msg.addr = client->addr; - msg.flags = 0; - msg.len = len; - msg.buf = data; - r = i2c_transfer(client->adapter, &msg, msg_count); - mutex_unlock(&picodlp_i2c_data->xfer_lock); - - /* - * i2c_transfer returns: - * number of messages sent in case of success - * a negative error number in case of failure - */ - if (r != msg_count) - goto err; - - /* In case of success */ - for (i = 0; i < len; i++) - dev_dbg(&client->dev, - "addr %x bw 0x%02x[%d]: 0x%02x\n", - client->addr, data[0] + i, i, data[i]); - - return 0; -err: - dev_err(&client->dev, "picodlp_i2c_write error\n"); - return r; -} - -static int picodlp_i2c_write(struct i2c_client *client, u8 reg, u32 value) -{ - u8 data[5]; - int i; - - data[0] = reg; - for (i = 1; i < 5; i++) - data[i] = (value >> (32 - (i) * 8)) & 0xFF; - - return picodlp_i2c_write_block(client, data, 5); -} - -static int picodlp_i2c_write_array(struct i2c_client *client, - const struct picodlp_i2c_command commands[], - int count) -{ - int i, r = 0; - for (i = 0; i < count; i++) { - r = picodlp_i2c_write(client, commands[i].reg, - commands[i].value); - if (r) - return r; - } - return r; -} - -static int picodlp_wait_for_dma_done(struct i2c_client *client) -{ - u8 trial = 100; - - do { - msleep(1); - if (!trial--) - return -ETIMEDOUT; - } while (picodlp_i2c_read(client, MAIN_STATUS) & DMA_STATUS); - - return 0; -} - -/** - * picodlp_i2c_init: i2c_initialization routine - * client: i2c_client for communication - * - * return - * 0 : Success, no error - * error code : Failure - */ -static int picodlp_i2c_init(struct i2c_client *client) -{ - int r; - static const struct picodlp_i2c_command init_cmd_set1[] = { - {SOFT_RESET, 1}, - {DMD_PARK_TRIGGER, 1}, - {MISC_REG, 5}, - {SEQ_CONTROL, 0}, - {SEQ_VECTOR, 0x100}, - {DMD_BLOCK_COUNT, 7}, - {DMD_VCC_CONTROL, 0x109}, - {DMD_PARK_PULSE_COUNT, 0xA}, - {DMD_PARK_PULSE_WIDTH, 0xB}, - {DMD_PARK_DELAY, 0x2ED}, - {DMD_SHADOW_ENABLE, 0}, - {FLASH_OPCODE, 0xB}, - {FLASH_DUMMY_BYTES, 1}, - {FLASH_ADDR_BYTES, 3}, - {PBC_CONTROL, 0}, - {FLASH_START_ADDR, CMT_LUT_0_START_ADDR}, - {FLASH_READ_BYTES, CMT_LUT_0_SIZE}, - {CMT_SPLASH_LUT_START_ADDR, 0}, - {CMT_SPLASH_LUT_DEST_SELECT, CMT_LUT_ALL}, - {PBC_CONTROL, 1}, - }; - - static const struct picodlp_i2c_command init_cmd_set2[] = { - {PBC_CONTROL, 0}, - {CMT_SPLASH_LUT_DEST_SELECT, 0}, - {PBC_CONTROL, 0}, - {FLASH_START_ADDR, SEQUENCE_0_START_ADDR}, - {FLASH_READ_BYTES, SEQUENCE_0_SIZE}, - {SEQ_RESET_LUT_START_ADDR, 0}, - {SEQ_RESET_LUT_DEST_SELECT, SEQ_SEQ_LUT}, - {PBC_CONTROL, 1}, - }; - - static const struct picodlp_i2c_command init_cmd_set3[] = { - {PBC_CONTROL, 0}, - {SEQ_RESET_LUT_DEST_SELECT, 0}, - {PBC_CONTROL, 0}, - {FLASH_START_ADDR, DRC_TABLE_0_START_ADDR}, - {FLASH_READ_BYTES, DRC_TABLE_0_SIZE}, - {SEQ_RESET_LUT_START_ADDR, 0}, - {SEQ_RESET_LUT_DEST_SELECT, SEQ_DRC_LUT_ALL}, - {PBC_CONTROL, 1}, - }; - - static const struct picodlp_i2c_command init_cmd_set4[] = { - {PBC_CONTROL, 0}, - {SEQ_RESET_LUT_DEST_SELECT, 0}, - {SDC_ENABLE, 1}, - {AGC_CTRL, 7}, - {CCA_C1A, 0x100}, - {CCA_C1B, 0x0}, - {CCA_C1C, 0x0}, - {CCA_C2A, 0x0}, - {CCA_C2B, 0x100}, - {CCA_C2C, 0x0}, - {CCA_C3A, 0x0}, - {CCA_C3B, 0x0}, - {CCA_C3C, 0x100}, - {CCA_C7A, 0x100}, - {CCA_C7B, 0x100}, - {CCA_C7C, 0x100}, - {CCA_ENABLE, 1}, - {CPU_IF_MODE, 1}, - {SHORT_FLIP, 1}, - {CURTAIN_CONTROL, 0}, - {DMD_PARK_TRIGGER, 0}, - {R_DRIVE_CURRENT, 0x298}, - {G_DRIVE_CURRENT, 0x298}, - {B_DRIVE_CURRENT, 0x298}, - {RGB_DRIVER_ENABLE, 7}, - {SEQ_CONTROL, 0}, - {ACTGEN_CONTROL, 0x10}, - {SEQUENCE_MODE, SEQ_LOCK}, - {DATA_FORMAT, RGB888}, - {INPUT_RESOLUTION, WVGA_864_LANDSCAPE}, - {INPUT_SOURCE, PARALLEL_RGB}, - {CPU_IF_SYNC_METHOD, 1}, - {SEQ_CONTROL, 1} - }; - - r = picodlp_i2c_write_array(client, init_cmd_set1, - ARRAY_SIZE(init_cmd_set1)); - if (r) - return r; - - r = picodlp_wait_for_dma_done(client); - if (r) - return r; - - r = picodlp_i2c_write_array(client, init_cmd_set2, - ARRAY_SIZE(init_cmd_set2)); - if (r) - return r; - - r = picodlp_wait_for_dma_done(client); - if (r) - return r; - - r = picodlp_i2c_write_array(client, init_cmd_set3, - ARRAY_SIZE(init_cmd_set3)); - if (r) - return r; - - r = picodlp_wait_for_dma_done(client); - if (r) - return r; - - r = picodlp_i2c_write_array(client, init_cmd_set4, - ARRAY_SIZE(init_cmd_set4)); - if (r) - return r; - - return 0; -} - -static int picodlp_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct picodlp_i2c_data *picodlp_i2c_data; - - picodlp_i2c_data = kzalloc(sizeof(struct picodlp_i2c_data), GFP_KERNEL); - - if (!picodlp_i2c_data) - return -ENOMEM; - - mutex_init(&picodlp_i2c_data->xfer_lock); - i2c_set_clientdata(client, picodlp_i2c_data); - - return 0; -} - -static int picodlp_i2c_remove(struct i2c_client *client) -{ - struct picodlp_i2c_data *picodlp_i2c_data = - i2c_get_clientdata(client); - kfree(picodlp_i2c_data); - return 0; -} - -static struct i2c_driver picodlp_i2c_driver = { - .driver = { - .name = "picodlp_i2c_driver", - }, - .probe = picodlp_i2c_probe, - .remove = picodlp_i2c_remove, - .id_table = picodlp_i2c_id, -}; - -static int picodlp_panel_power_on(struct omap_dss_device *dssdev) -{ - int r, trial = 100; - struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); - struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); - - gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); - msleep(1); - gpio_set_value(picodlp_pdata->pwrgood_gpio, 1); - - while (!gpio_get_value(picodlp_pdata->emu_done_gpio)) { - if (!trial--) { - dev_err(dssdev->dev, "emu_done signal not" - " going high\n"); - return -ETIMEDOUT; - } - msleep(5); - } - /* - * As per dpp2600 programming guide, - * it is required to sleep for 1000ms after emu_done signal goes high - * then only i2c commands can be successfully sent to dpp2600 - */ - msleep(1000); - - omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); - - r = omapdss_dpi_display_enable(dssdev); - if (r) { - dev_err(dssdev->dev, "failed to enable DPI\n"); - goto err1; - } - - r = picodlp_i2c_init(picod->picodlp_i2c_client); - if (r) - goto err; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - return r; -err: - omapdss_dpi_display_disable(dssdev); -err1: - return r; -} - -static void picodlp_panel_power_off(struct omap_dss_device *dssdev) -{ - struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); - - omapdss_dpi_display_disable(dssdev); - - gpio_set_value(picodlp_pdata->emu_done_gpio, 0); - gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); -} - -static int picodlp_panel_probe(struct omap_dss_device *dssdev) -{ - struct picodlp_data *picod; - struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); - struct i2c_adapter *adapter; - struct i2c_client *picodlp_i2c_client; - int r, picodlp_adapter_id; - - dssdev->panel.timings = pico_ls_timings; - - if (!picodlp_pdata) - return -EINVAL; - - picod = devm_kzalloc(dssdev->dev, sizeof(*picod), GFP_KERNEL); - if (!picod) - return -ENOMEM; - - mutex_init(&picod->lock); - - picodlp_adapter_id = picodlp_pdata->picodlp_adapter_id; - - adapter = i2c_get_adapter(picodlp_adapter_id); - if (!adapter) { - dev_err(dssdev->dev, "can't get i2c adapter\n"); - return -ENODEV; - } - - picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info); - if (!picodlp_i2c_client) { - dev_err(dssdev->dev, "can't add i2c device::" - " picodlp_i2c_client is NULL\n"); - return -ENODEV; - } - - picod->picodlp_i2c_client = picodlp_i2c_client; - - dev_set_drvdata(dssdev->dev, picod); - - if (gpio_is_valid(picodlp_pdata->emu_done_gpio)) { - r = devm_gpio_request_one(dssdev->dev, - picodlp_pdata->emu_done_gpio, - GPIOF_IN, "DLP EMU DONE"); - if (r) - return r; - } - - if (gpio_is_valid(picodlp_pdata->pwrgood_gpio)) { - r = devm_gpio_request_one(dssdev->dev, - picodlp_pdata->pwrgood_gpio, - GPIOF_OUT_INIT_LOW, "DLP PWRGOOD"); - if (r) - return r; - } - - return 0; -} - -static void picodlp_panel_remove(struct omap_dss_device *dssdev) -{ - struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); - - i2c_unregister_device(picod->picodlp_i2c_client); - dev_set_drvdata(dssdev->dev, NULL); - dev_dbg(dssdev->dev, "removing picodlp panel\n"); -} - -static int picodlp_panel_enable(struct omap_dss_device *dssdev) -{ - struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); - int r; - - dev_dbg(dssdev->dev, "enabling picodlp panel\n"); - - mutex_lock(&picod->lock); - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { - mutex_unlock(&picod->lock); - return -EINVAL; - } - - r = picodlp_panel_power_on(dssdev); - mutex_unlock(&picod->lock); - - return r; -} - -static void picodlp_panel_disable(struct omap_dss_device *dssdev) -{ - struct picodlp_data *picod = dev_get_drvdata(dssdev->dev); - - mutex_lock(&picod->lock); - /* Turn off DLP Power */ - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - picodlp_panel_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - mutex_unlock(&picod->lock); - - dev_dbg(dssdev->dev, "disabling picodlp panel\n"); -} - -static void picodlp_get_resolution(struct omap_dss_device *dssdev, - u16 *xres, u16 *yres) -{ - *xres = dssdev->panel.timings.x_res; - *yres = dssdev->panel.timings.y_res; -} - -static struct omap_dss_driver picodlp_driver = { - .probe = picodlp_panel_probe, - .remove = picodlp_panel_remove, - - .enable = picodlp_panel_enable, - .disable = picodlp_panel_disable, - - .get_resolution = picodlp_get_resolution, - - .driver = { - .name = "picodlp_panel", - .owner = THIS_MODULE, - }, -}; - -static int __init picodlp_init(void) -{ - int r = 0; - - r = i2c_add_driver(&picodlp_i2c_driver); - if (r) { - printk(KERN_WARNING "picodlp_i2c_driver" \ - " registration failed\n"); - return r; - } - - r = omap_dss_register_driver(&picodlp_driver); - if (r) - i2c_del_driver(&picodlp_i2c_driver); - - return r; -} - -static void __exit picodlp_exit(void) -{ - i2c_del_driver(&picodlp_i2c_driver); - omap_dss_unregister_driver(&picodlp_driver); -} - -module_init(picodlp_init); -module_exit(picodlp_exit); - -MODULE_AUTHOR("Mythri P K <mythripk@ti.com>"); -MODULE_DESCRIPTION("picodlp driver"); -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 @@ -/* - * Header file required by picodlp panel driver - * - * Copyright (C) 2009-2011 Texas Instruments - * Author: Mythri P K <mythripk@ti.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __OMAP2_DISPLAY_PANEL_PICODLP_H -#define __OMAP2_DISPLAY_PANEL_PICODLP_H - -/* Commands used for configuring picodlp panel */ - -#define MAIN_STATUS 0x03 -#define PBC_CONTROL 0x08 -#define INPUT_SOURCE 0x0B -#define INPUT_RESOLUTION 0x0C -#define DATA_FORMAT 0x0D -#define IMG_ROTATION 0x0E -#define LONG_FLIP 0x0F -#define SHORT_FLIP 0x10 -#define TEST_PAT_SELECT 0x11 -#define R_DRIVE_CURRENT 0x12 -#define G_DRIVE_CURRENT 0x13 -#define B_DRIVE_CURRENT 0x14 -#define READ_REG_SELECT 0x15 -#define RGB_DRIVER_ENABLE 0x16 - -#define CPU_IF_MODE 0x18 -#define FRAME_RATE 0x19 -#define CPU_IF_SYNC_METHOD 0x1A -#define CPU_IF_SOF 0x1B -#define CPU_IF_EOF 0x1C -#define CPU_IF_SLEEP 0x1D - -#define SEQUENCE_MODE 0x1E -#define SOFT_RESET 0x1F -#define FRONT_END_RESET 0x21 -#define AUTO_PWR_ENABLE 0x22 - -#define VSYNC_LINE_DELAY 0x23 -#define CPU_PI_HORIZ_START 0x24 -#define CPU_PI_VERT_START 0x25 -#define CPU_PI_HORIZ_WIDTH 0x26 -#define CPU_PI_VERT_HEIGHT 0x27 - -#define PIXEL_MASK_CROP 0x28 -#define CROP_FIRST_LINE 0x29 -#define CROP_LAST_LINE 0x2A -#define CROP_FIRST_PIXEL 0x2B -#define CROP_LAST_PIXEL 0x2C -#define DMD_PARK_TRIGGER 0x2D - -#define MISC_REG 0x30 - -/* AGC registers */ -#define AGC_CTRL 0x50 -#define AGC_CLIPPED_PIXS 0x55 -#define AGC_BRIGHT_PIXS 0x56 -#define AGC_BG_PIXS 0x57 -#define AGC_SAFETY_MARGIN 0x17 - -/* Color Coordinate Adjustment registers */ -#define CCA_ENABLE 0x5E -#define CCA_C1A 0x5F -#define CCA_C1B 0x60 -#define CCA_C1C 0x61 -#define CCA_C2A 0x62 -#define CCA_C2B 0x63 -#define CCA_C2C 0x64 -#define CCA_C3A 0x65 -#define CCA_C3B 0x66 -#define CCA_C3C 0x67 -#define CCA_C7A 0x71 -#define CCA_C7B 0x72 -#define CCA_C7C 0x73 - -/** - * DLP Pico Processor 2600 comes with flash - * We can do DMA operations from flash for accessing Look Up Tables - */ -#define DMA_STATUS 0x100 -#define FLASH_ADDR_BYTES 0x74 -#define FLASH_DUMMY_BYTES 0x75 -#define FLASH_WRITE_BYTES 0x76 -#define FLASH_READ_BYTES 0x77 -#define FLASH_OPCODE 0x78 -#define FLASH_START_ADDR 0x79 -#define FLASH_DUMMY2 0x7A -#define FLASH_WRITE_DATA 0x7B - -#define TEMPORAL_DITH_DISABLE 0x7E -#define SEQ_CONTROL 0x82 -#define SEQ_VECTOR 0x83 - -/* DMD is Digital Micromirror Device */ -#define DMD_BLOCK_COUNT 0x84 -#define DMD_VCC_CONTROL 0x86 -#define DMD_PARK_PULSE_COUNT 0x87 -#define DMD_PARK_PULSE_WIDTH 0x88 -#define DMD_PARK_DELAY 0x89 -#define DMD_SHADOW_ENABLE 0x8E -#define SEQ_STATUS 0x8F -#define FLASH_CLOCK_CONTROL 0x98 -#define DMD_PARK 0x2D - -#define SDRAM_BIST_ENABLE 0x46 -#define DDR_DRIVER_STRENGTH 0x9A -#define SDC_ENABLE 0x9D -#define SDC_BUFF_SWAP_DISABLE 0xA3 -#define CURTAIN_CONTROL 0xA6 -#define DDR_BUS_SWAP_ENABLE 0xA7 -#define DMD_TRC_ENABLE 0xA8 -#define DMD_BUS_SWAP_ENABLE 0xA9 - -#define ACTGEN_ENABLE 0xAE -#define ACTGEN_CONTROL 0xAF -#define ACTGEN_HORIZ_BP 0xB0 -#define ACTGEN_VERT_BP 0xB1 - -/* Look Up Table access */ -#define CMT_SPLASH_LUT_START_ADDR 0xFA -#define CMT_SPLASH_LUT_DEST_SELECT 0xFB -#define CMT_SPLASH_LUT_DATA 0xFC -#define SEQ_RESET_LUT_START_ADDR 0xFD -#define SEQ_RESET_LUT_DEST_SELECT 0xFE -#define SEQ_RESET_LUT_DATA 0xFF - -/* Input source definitions */ -#define PARALLEL_RGB 0 -#define INT_TEST_PATTERN 1 -#define SPLASH_SCREEN 2 -#define CPU_INTF 3 -#define BT656 4 - -/* Standard input resolution definitions */ -#define QWVGA_LANDSCAPE 3 /* (427h*240v) */ -#define WVGA_864_LANDSCAPE 21 /* (864h*480v) */ -#define WVGA_DMD_OPTICAL_TEST 35 /* (608h*684v) */ - -/* Standard data format definitions */ -#define RGB565 0 -#define RGB666 1 -#define RGB888 2 - -/* Test Pattern definitions */ -#define TPG_CHECKERBOARD 0 -#define TPG_BLACK 1 -#define TPG_WHITE 2 -#define TPG_RED 3 -#define TPG_BLUE 4 -#define TPG_GREEN 5 -#define TPG_VLINES_BLACK 6 -#define TPG_HLINES_BLACK 7 -#define TPG_VLINES_ALT 8 -#define TPG_HLINES_ALT 9 -#define TPG_DIAG_LINES 10 -#define TPG_GREYRAMP_VERT 11 -#define TPG_GREYRAMP_HORIZ 12 -#define TPG_ANSI_CHECKERBOARD 13 - -/* sequence mode definitions */ -#define SEQ_FREE_RUN 0 -#define SEQ_LOCK 1 - -/* curtain color definitions */ -#define CURTAIN_BLACK 0 -#define CURTAIN_RED 1 -#define CURTAIN_GREEN 2 -#define CURTAIN_BLUE 3 -#define CURTAIN_YELLOW 4 -#define CURTAIN_MAGENTA 5 -#define CURTAIN_CYAN 6 -#define CURTAIN_WHITE 7 - -/* LUT definitions */ -#define CMT_LUT_NONE 0 -#define CMT_LUT_GREEN 1 -#define CMT_LUT_RED 2 -#define CMT_LUT_BLUE 3 -#define CMT_LUT_ALL 4 -#define SPLASH_LUT 5 - -#define SEQ_LUT_NONE 0 -#define SEQ_DRC_LUT_0 1 -#define SEQ_DRC_LUT_1 2 -#define SEQ_DRC_LUT_2 3 -#define SEQ_DRC_LUT_3 4 -#define SEQ_SEQ_LUT 5 -#define SEQ_DRC_LUT_ALL 6 -#define WPC_PROGRAM_LUT 7 - -#define BITSTREAM_START_ADDR 0x00000000 -#define BITSTREAM_SIZE 0x00040000 - -#define WPC_FW_0_START_ADDR 0x00040000 -#define WPC_FW_0_SIZE 0x00000ce8 - -#define SEQUENCE_0_START_ADDR 0x00044000 -#define SEQUENCE_0_SIZE 0x00001000 - -#define SEQUENCE_1_START_ADDR 0x00045000 -#define SEQUENCE_1_SIZE 0x00000d10 - -#define SEQUENCE_2_START_ADDR 0x00046000 -#define SEQUENCE_2_SIZE 0x00000d10 - -#define SEQUENCE_3_START_ADDR 0x00047000 -#define SEQUENCE_3_SIZE 0x00000d10 - -#define SEQUENCE_4_START_ADDR 0x00048000 -#define SEQUENCE_4_SIZE 0x00000d10 - -#define SEQUENCE_5_START_ADDR 0x00049000 -#define SEQUENCE_5_SIZE 0x00000d10 - -#define SEQUENCE_6_START_ADDR 0x0004a000 -#define SEQUENCE_6_SIZE 0x00000d10 - -#define CMT_LUT_0_START_ADDR 0x0004b200 -#define CMT_LUT_0_SIZE 0x00000600 - -#define CMT_LUT_1_START_ADDR 0x0004b800 -#define CMT_LUT_1_SIZE 0x00000600 - -#define CMT_LUT_2_START_ADDR 0x0004be00 -#define CMT_LUT_2_SIZE 0x00000600 - -#define CMT_LUT_3_START_ADDR 0x0004c400 -#define CMT_LUT_3_SIZE 0x00000600 - -#define CMT_LUT_4_START_ADDR 0x0004ca00 -#define CMT_LUT_4_SIZE 0x00000600 - -#define CMT_LUT_5_START_ADDR 0x0004d000 -#define CMT_LUT_5_SIZE 0x00000600 - -#define CMT_LUT_6_START_ADDR 0x0004d600 -#define CMT_LUT_6_SIZE 0x00000600 - -#define DRC_TABLE_0_START_ADDR 0x0004dc00 -#define DRC_TABLE_0_SIZE 0x00000100 - -#define SPLASH_0_START_ADDR 0x0004dd00 -#define SPLASH_0_SIZE 0x00032280 - -#define SEQUENCE_7_START_ADDR 0x00080000 -#define SEQUENCE_7_SIZE 0x00000d10 - -#define SEQUENCE_8_START_ADDR 0x00081800 -#define SEQUENCE_8_SIZE 0x00000d10 - -#define SEQUENCE_9_START_ADDR 0x00083000 -#define SEQUENCE_9_SIZE 0x00000d10 - -#define CMT_LUT_7_START_ADDR 0x0008e000 -#define CMT_LUT_7_SIZE 0x00000600 - -#define CMT_LUT_8_START_ADDR 0x0008e800 -#define CMT_LUT_8_SIZE 0x00000600 - -#define CMT_LUT_9_START_ADDR 0x0008f000 -#define CMT_LUT_9_SIZE 0x00000600 - -#define SPLASH_1_START_ADDR 0x0009a000 -#define SPLASH_1_SIZE 0x00032280 - -#define SPLASH_2_START_ADDR 0x000cd000 -#define SPLASH_2_SIZE 0x00032280 - -#define SPLASH_3_START_ADDR 0x00100000 -#define SPLASH_3_SIZE 0x00032280 - -#define OPT_SPLASH_0_START_ADDR 0x00134000 -#define OPT_SPLASH_0_SIZE 0x000cb100 - -#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 @@ -/* - * LCD panel driver for Sharp LS037V7DW01 - * - * Copyright (C) 2008 Nokia Corporation - * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/fb.h> -#include <linux/err.h> -#include <linux/slab.h> -#include <linux/gpio.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -static struct omap_video_timings sharp_ls_timings = { - .x_res = 480, - .y_res = 640, - - .pixel_clock = 19200, - - .hsw = 2, - .hfp = 1, - .hbp = 28, - - .vsw = 1, - .vfp = 1, - .vbp = 1, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, -}; - -static inline struct panel_sharp_ls037v7dw01_data -*get_panel_data(const struct omap_dss_device *dssdev) -{ - return (struct panel_sharp_ls037v7dw01_data *) dssdev->data; -} - -static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) -{ - struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev); - int r; - - if (!pd) - return -EINVAL; - - dssdev->panel.timings = sharp_ls_timings; - - if (gpio_is_valid(pd->mo_gpio)) { - r = devm_gpio_request_one(dssdev->dev, pd->mo_gpio, - GPIOF_OUT_INIT_LOW, "lcd MO"); - if (r) - return r; - } - - if (gpio_is_valid(pd->lr_gpio)) { - r = devm_gpio_request_one(dssdev->dev, pd->lr_gpio, - GPIOF_OUT_INIT_HIGH, "lcd LR"); - if (r) - return r; - } - - if (gpio_is_valid(pd->ud_gpio)) { - r = devm_gpio_request_one(dssdev->dev, pd->ud_gpio, - GPIOF_OUT_INIT_HIGH, "lcd UD"); - if (r) - return r; - } - - if (gpio_is_valid(pd->resb_gpio)) { - r = devm_gpio_request_one(dssdev->dev, pd->resb_gpio, - GPIOF_OUT_INIT_LOW, "lcd RESB"); - if (r) - return r; - } - - if (gpio_is_valid(pd->ini_gpio)) { - r = devm_gpio_request_one(dssdev->dev, pd->ini_gpio, - GPIOF_OUT_INIT_LOW, "lcd INI"); - if (r) - return r; - } - - return 0; -} - -static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev) -{ -} - -static int sharp_ls_power_on(struct omap_dss_device *dssdev) -{ - struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev); - int r = 0; - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); - - r = omapdss_dpi_display_enable(dssdev); - if (r) - goto err0; - - /* wait couple of vsyncs until enabling the LCD */ - msleep(50); - - if (gpio_is_valid(pd->resb_gpio)) - gpio_set_value_cansleep(pd->resb_gpio, 1); - - if (gpio_is_valid(pd->ini_gpio)) - gpio_set_value_cansleep(pd->ini_gpio, 1); - - return 0; -err0: - return r; -} - -static void sharp_ls_power_off(struct omap_dss_device *dssdev) -{ - struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - if (gpio_is_valid(pd->ini_gpio)) - gpio_set_value_cansleep(pd->ini_gpio, 0); - - if (gpio_is_valid(pd->resb_gpio)) - gpio_set_value_cansleep(pd->resb_gpio, 0); - - /* wait at least 5 vsyncs after disabling the LCD */ - - msleep(100); - - omapdss_dpi_display_disable(dssdev); -} - -static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) -{ - int r; - r = sharp_ls_power_on(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - return r; -} - -static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) -{ - sharp_ls_power_off(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -} - -static struct omap_dss_driver sharp_ls_driver = { - .probe = sharp_ls_panel_probe, - .remove = __exit_p(sharp_ls_panel_remove), - - .enable = sharp_ls_panel_enable, - .disable = sharp_ls_panel_disable, - - .driver = { - .name = "sharp_ls_panel", - .owner = THIS_MODULE, - }, -}; - -static int __init sharp_ls_panel_drv_init(void) -{ - return omap_dss_register_driver(&sharp_ls_driver); -} - -static void __exit sharp_ls_panel_drv_exit(void) -{ - omap_dss_unregister_driver(&sharp_ls_driver); -} - -module_init(sharp_ls_panel_drv_init); -module_exit(sharp_ls_panel_drv_exit); -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 @@ -/* - * Taal DSI command mode panel - * - * Copyright (C) 2009 Nokia Corporation - * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/*#define DEBUG*/ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/jiffies.h> -#include <linux/sched.h> -#include <linux/backlight.h> -#include <linux/fb.h> -#include <linux/interrupt.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> -#include <linux/slab.h> -#include <linux/mutex.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> -#include <video/mipi_display.h> - -/* DSI Virtual channel. Hardcoded for now. */ -#define TCH 0 - -#define DCS_READ_NUM_ERRORS 0x05 -#define DCS_BRIGHTNESS 0x51 -#define DCS_CTRL_DISPLAY 0x53 -#define DCS_WRITE_CABC 0x55 -#define DCS_READ_CABC 0x56 -#define DCS_GET_ID1 0xda -#define DCS_GET_ID2 0xdb -#define DCS_GET_ID3 0xdc - -static irqreturn_t taal_te_isr(int irq, void *data); -static void taal_te_timeout_work_callback(struct work_struct *work); -static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); - -static int taal_panel_reset(struct omap_dss_device *dssdev); - -struct taal_data { - struct mutex lock; - - struct backlight_device *bldev; - - unsigned long hw_guard_end; /* next value of jiffies when we can - * issue the next sleep in/out command - */ - unsigned long hw_guard_wait; /* max guard time in jiffies */ - - struct omap_dss_device *dssdev; - - /* panel HW configuration from DT or platform data */ - int reset_gpio; - int ext_te_gpio; - - bool use_dsi_backlight; - - struct omap_dsi_pin_config pin_config; - - /* runtime variables */ - bool enabled; - - bool te_enabled; - - atomic_t do_update; - int channel; - - struct delayed_work te_timeout_work; - - bool cabc_broken; - unsigned cabc_mode; - - bool intro_printed; - - struct workqueue_struct *workqueue; - - struct delayed_work esd_work; - unsigned esd_interval; - - bool ulps_enabled; - unsigned ulps_timeout; - struct delayed_work ulps_work; -}; - -static void taal_esd_work(struct work_struct *work); -static void taal_ulps_work(struct work_struct *work); - -static void hw_guard_start(struct taal_data *td, int guard_msec) -{ - td->hw_guard_wait = msecs_to_jiffies(guard_msec); - td->hw_guard_end = jiffies + td->hw_guard_wait; -} - -static void hw_guard_wait(struct taal_data *td) -{ - unsigned long wait = td->hw_guard_end - jiffies; - - if ((long)wait > 0 && wait <= td->hw_guard_wait) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(wait); - } -} - -static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data) -{ - int r; - u8 buf[1]; - - r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1); - - if (r < 0) - return r; - - *data = buf[0]; - - return 0; -} - -static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd) -{ - return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1); -} - -static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param) -{ - u8 buf[2]; - buf[0] = dcs_cmd; - buf[1] = param; - return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2); -} - -static int taal_sleep_in(struct taal_data *td) - -{ - u8 cmd; - int r; - - hw_guard_wait(td); - - cmd = MIPI_DCS_ENTER_SLEEP_MODE; - r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1); - if (r) - return r; - - hw_guard_start(td, 120); - - msleep(5); - - return 0; -} - -static int taal_sleep_out(struct taal_data *td) -{ - int r; - - hw_guard_wait(td); - - r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE); - if (r) - return r; - - hw_guard_start(td, 120); - - msleep(5); - - return 0; -} - -static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3) -{ - int r; - - r = taal_dcs_read_1(td, DCS_GET_ID1, id1); - if (r) - return r; - r = taal_dcs_read_1(td, DCS_GET_ID2, id2); - if (r) - return r; - r = taal_dcs_read_1(td, DCS_GET_ID3, id3); - if (r) - return r; - - return 0; -} - -static int taal_set_update_window(struct taal_data *td, - u16 x, u16 y, u16 w, u16 h) -{ - int r; - u16 x1 = x; - u16 x2 = x + w - 1; - u16 y1 = y; - u16 y2 = y + h - 1; - - u8 buf[5]; - buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS; - buf[1] = (x1 >> 8) & 0xff; - buf[2] = (x1 >> 0) & 0xff; - buf[3] = (x2 >> 8) & 0xff; - buf[4] = (x2 >> 0) & 0xff; - - r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf)); - if (r) - return r; - - buf[0] = MIPI_DCS_SET_PAGE_ADDRESS; - buf[1] = (y1 >> 8) & 0xff; - buf[2] = (y1 >> 0) & 0xff; - buf[3] = (y2 >> 8) & 0xff; - buf[4] = (y2 >> 0) & 0xff; - - r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf)); - if (r) - return r; - - dsi_vc_send_bta_sync(td->dssdev, td->channel); - - return r; -} - -static void taal_queue_esd_work(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - if (td->esd_interval > 0) - queue_delayed_work(td->workqueue, &td->esd_work, - msecs_to_jiffies(td->esd_interval)); -} - -static void taal_cancel_esd_work(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - cancel_delayed_work(&td->esd_work); -} - -static void taal_queue_ulps_work(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - if (td->ulps_timeout > 0) - queue_delayed_work(td->workqueue, &td->ulps_work, - msecs_to_jiffies(td->ulps_timeout)); -} - -static void taal_cancel_ulps_work(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - cancel_delayed_work(&td->ulps_work); -} - -static int taal_enter_ulps(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - if (td->ulps_enabled) - return 0; - - taal_cancel_ulps_work(dssdev); - - r = _taal_enable_te(dssdev, false); - if (r) - goto err; - - if (gpio_is_valid(td->ext_te_gpio)) - disable_irq(gpio_to_irq(td->ext_te_gpio)); - - omapdss_dsi_display_disable(dssdev, false, true); - - td->ulps_enabled = true; - - return 0; - -err: - dev_err(dssdev->dev, "enter ULPS failed"); - taal_panel_reset(dssdev); - - td->ulps_enabled = false; - - taal_queue_ulps_work(dssdev); - - return r; -} - -static int taal_exit_ulps(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - if (!td->ulps_enabled) - return 0; - - r = omapdss_dsi_display_enable(dssdev); - if (r) { - dev_err(dssdev->dev, "failed to enable DSI\n"); - goto err1; - } - - omapdss_dsi_vc_enable_hs(dssdev, td->channel, true); - - r = _taal_enable_te(dssdev, true); - if (r) { - dev_err(dssdev->dev, "failed to re-enable TE"); - goto err2; - } - - if (gpio_is_valid(td->ext_te_gpio)) - enable_irq(gpio_to_irq(td->ext_te_gpio)); - - taal_queue_ulps_work(dssdev); - - td->ulps_enabled = false; - - return 0; - -err2: - dev_err(dssdev->dev, "failed to exit ULPS"); - - r = taal_panel_reset(dssdev); - if (!r) { - if (gpio_is_valid(td->ext_te_gpio)) - enable_irq(gpio_to_irq(td->ext_te_gpio)); - td->ulps_enabled = false; - } -err1: - taal_queue_ulps_work(dssdev); - - return r; -} - -static int taal_wake_up(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - if (td->ulps_enabled) - return taal_exit_ulps(dssdev); - - taal_cancel_ulps_work(dssdev); - taal_queue_ulps_work(dssdev); - return 0; -} - -static int taal_bl_update_status(struct backlight_device *dev) -{ - struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - int level; - - if (dev->props.fb_blank == FB_BLANK_UNBLANK && - dev->props.power == FB_BLANK_UNBLANK) - level = dev->props.brightness; - else - level = 0; - - dev_dbg(dssdev->dev, "update brightness to %d\n", level); - - mutex_lock(&td->lock); - - if (td->enabled) { - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (!r) - r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level); - - dsi_bus_unlock(dssdev); - } else { - r = 0; - } - - mutex_unlock(&td->lock); - - return r; -} - -static int taal_bl_get_intensity(struct backlight_device *dev) -{ - if (dev->props.fb_blank == FB_BLANK_UNBLANK && - dev->props.power == FB_BLANK_UNBLANK) - return dev->props.brightness; - - return 0; -} - -static const struct backlight_ops taal_bl_ops = { - .get_brightness = taal_bl_get_intensity, - .update_status = taal_bl_update_status, -}; - -static void taal_get_resolution(struct omap_dss_device *dssdev, - u16 *xres, u16 *yres) -{ - *xres = dssdev->panel.timings.x_res; - *yres = dssdev->panel.timings.y_res; -} - -static ssize_t taal_num_errors_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - u8 errors = 0; - int r; - - mutex_lock(&td->lock); - - if (td->enabled) { - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (!r) - r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors); - - dsi_bus_unlock(dssdev); - } else { - r = -ENODEV; - } - - mutex_unlock(&td->lock); - - if (r) - return r; - - return snprintf(buf, PAGE_SIZE, "%d\n", errors); -} - -static ssize_t taal_hw_revision_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - u8 id1, id2, id3; - int r; - - mutex_lock(&td->lock); - - if (td->enabled) { - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (!r) - r = taal_get_id(td, &id1, &id2, &id3); - - dsi_bus_unlock(dssdev); - } else { - r = -ENODEV; - } - - mutex_unlock(&td->lock); - - if (r) - return r; - - return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x\n", id1, id2, id3); -} - -static const char *cabc_modes[] = { - "off", /* used also always when CABC is not supported */ - "ui", - "still-image", - "moving-image", -}; - -static ssize_t show_cabc_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - const char *mode_str; - int mode; - int len; - - mode = td->cabc_mode; - - mode_str = "unknown"; - if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes)) - mode_str = cabc_modes[mode]; - len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str); - - return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1; -} - -static ssize_t store_cabc_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int i; - int r; - - for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) { - if (sysfs_streq(cabc_modes[i], buf)) - break; - } - - if (i == ARRAY_SIZE(cabc_modes)) - return -EINVAL; - - mutex_lock(&td->lock); - - if (td->enabled) { - dsi_bus_lock(dssdev); - - if (!td->cabc_broken) { - r = taal_wake_up(dssdev); - if (r) - goto err; - - r = taal_dcs_write_1(td, DCS_WRITE_CABC, i); - if (r) - goto err; - } - - dsi_bus_unlock(dssdev); - } - - td->cabc_mode = i; - - mutex_unlock(&td->lock); - - return count; -err: - dsi_bus_unlock(dssdev); - mutex_unlock(&td->lock); - return r; -} - -static ssize_t show_cabc_available_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int len; - int i; - - for (i = 0, len = 0; - len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++) - len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s", - i ? " " : "", cabc_modes[i], - i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : ""); - - return len < PAGE_SIZE ? len : PAGE_SIZE - 1; -} - -static ssize_t taal_store_esd_interval(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - unsigned long t; - int r; - - r = kstrtoul(buf, 10, &t); - if (r) - return r; - - mutex_lock(&td->lock); - taal_cancel_esd_work(dssdev); - td->esd_interval = t; - if (td->enabled) - taal_queue_esd_work(dssdev); - mutex_unlock(&td->lock); - - return count; -} - -static ssize_t taal_show_esd_interval(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - unsigned t; - - mutex_lock(&td->lock); - t = td->esd_interval; - mutex_unlock(&td->lock); - - return snprintf(buf, PAGE_SIZE, "%u\n", t); -} - -static ssize_t taal_store_ulps(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - unsigned long t; - int r; - - r = kstrtoul(buf, 10, &t); - if (r) - return r; - - mutex_lock(&td->lock); - - if (td->enabled) { - dsi_bus_lock(dssdev); - - if (t) - r = taal_enter_ulps(dssdev); - else - r = taal_wake_up(dssdev); - - dsi_bus_unlock(dssdev); - } - - mutex_unlock(&td->lock); - - if (r) - return r; - - return count; -} - -static ssize_t taal_show_ulps(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - unsigned t; - - mutex_lock(&td->lock); - t = td->ulps_enabled; - mutex_unlock(&td->lock); - - return snprintf(buf, PAGE_SIZE, "%u\n", t); -} - -static ssize_t taal_store_ulps_timeout(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - unsigned long t; - int r; - - r = kstrtoul(buf, 10, &t); - if (r) - return r; - - mutex_lock(&td->lock); - td->ulps_timeout = t; - - if (td->enabled) { - /* taal_wake_up will restart the timer */ - dsi_bus_lock(dssdev); - r = taal_wake_up(dssdev); - dsi_bus_unlock(dssdev); - } - - mutex_unlock(&td->lock); - - if (r) - return r; - - return count; -} - -static ssize_t taal_show_ulps_timeout(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - struct taal_data *td = dev_get_drvdata(dssdev->dev); - unsigned t; - - mutex_lock(&td->lock); - t = td->ulps_timeout; - mutex_unlock(&td->lock); - - return snprintf(buf, PAGE_SIZE, "%u\n", t); -} - -static DEVICE_ATTR(num_dsi_errors, S_IRUGO, taal_num_errors_show, NULL); -static DEVICE_ATTR(hw_revision, S_IRUGO, taal_hw_revision_show, NULL); -static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR, - show_cabc_mode, store_cabc_mode); -static DEVICE_ATTR(cabc_available_modes, S_IRUGO, - show_cabc_available_modes, NULL); -static DEVICE_ATTR(esd_interval, S_IRUGO | S_IWUSR, - taal_show_esd_interval, taal_store_esd_interval); -static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR, - taal_show_ulps, taal_store_ulps); -static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR, - taal_show_ulps_timeout, taal_store_ulps_timeout); - -static struct attribute *taal_attrs[] = { - &dev_attr_num_dsi_errors.attr, - &dev_attr_hw_revision.attr, - &dev_attr_cabc_mode.attr, - &dev_attr_cabc_available_modes.attr, - &dev_attr_esd_interval.attr, - &dev_attr_ulps.attr, - &dev_attr_ulps_timeout.attr, - NULL, -}; - -static struct attribute_group taal_attr_group = { - .attrs = taal_attrs, -}; - -static void taal_hw_reset(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - if (!gpio_is_valid(td->reset_gpio)) - return; - - gpio_set_value(td->reset_gpio, 1); - udelay(10); - /* reset the panel */ - gpio_set_value(td->reset_gpio, 0); - /* assert reset */ - udelay(10); - gpio_set_value(td->reset_gpio, 1); - /* wait after releasing reset */ - msleep(5); -} - -static void taal_probe_pdata(struct taal_data *td, - const struct nokia_dsi_panel_data *pdata) -{ - td->reset_gpio = pdata->reset_gpio; - - if (pdata->use_ext_te) - td->ext_te_gpio = pdata->ext_te_gpio; - else - td->ext_te_gpio = -1; - - td->esd_interval = pdata->esd_interval; - td->ulps_timeout = pdata->ulps_timeout; - - td->use_dsi_backlight = pdata->use_dsi_backlight; - - td->pin_config = pdata->pin_config; -} - -static int taal_probe(struct omap_dss_device *dssdev) -{ - struct backlight_properties props; - struct taal_data *td; - struct backlight_device *bldev = NULL; - int r; - - dev_dbg(dssdev->dev, "probe\n"); - - td = devm_kzalloc(dssdev->dev, sizeof(*td), GFP_KERNEL); - if (!td) - return -ENOMEM; - - dev_set_drvdata(dssdev->dev, td); - td->dssdev = dssdev; - - if (dssdev->data) { - const struct nokia_dsi_panel_data *pdata = dssdev->data; - - taal_probe_pdata(td, pdata); - } else { - return -ENODEV; - } - - dssdev->panel.timings.x_res = 864; - dssdev->panel.timings.y_res = 480; - dssdev->panel.timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000); - dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; - dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | - OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; - - mutex_init(&td->lock); - - atomic_set(&td->do_update, 0); - - if (gpio_is_valid(td->reset_gpio)) { - r = devm_gpio_request_one(dssdev->dev, td->reset_gpio, - GPIOF_OUT_INIT_LOW, "taal rst"); - if (r) { - dev_err(dssdev->dev, "failed to request reset gpio\n"); - return r; - } - } - - if (gpio_is_valid(td->ext_te_gpio)) { - r = devm_gpio_request_one(dssdev->dev, td->ext_te_gpio, - GPIOF_IN, "taal irq"); - if (r) { - dev_err(dssdev->dev, "GPIO request failed\n"); - return r; - } - - r = devm_request_irq(dssdev->dev, gpio_to_irq(td->ext_te_gpio), - taal_te_isr, - IRQF_TRIGGER_RISING, - "taal vsync", dssdev); - - if (r) { - dev_err(dssdev->dev, "IRQ request failed\n"); - return r; - } - - INIT_DEFERRABLE_WORK(&td->te_timeout_work, - taal_te_timeout_work_callback); - - dev_dbg(dssdev->dev, "Using GPIO TE\n"); - } - - td->workqueue = create_singlethread_workqueue("taal_esd"); - if (td->workqueue == NULL) { - dev_err(dssdev->dev, "can't create ESD workqueue\n"); - return -ENOMEM; - } - INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work); - INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work); - - taal_hw_reset(dssdev); - - if (td->use_dsi_backlight) { - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = 255; - - props.type = BACKLIGHT_RAW; - bldev = backlight_device_register(dev_name(dssdev->dev), - dssdev->dev, dssdev, &taal_bl_ops, &props); - if (IS_ERR(bldev)) { - r = PTR_ERR(bldev); - goto err_bl; - } - - td->bldev = bldev; - - bldev->props.fb_blank = FB_BLANK_UNBLANK; - bldev->props.power = FB_BLANK_UNBLANK; - bldev->props.brightness = 255; - - taal_bl_update_status(bldev); - } - - r = omap_dsi_request_vc(dssdev, &td->channel); - if (r) { - dev_err(dssdev->dev, "failed to get virtual channel\n"); - goto err_req_vc; - } - - r = omap_dsi_set_vc_id(dssdev, td->channel, TCH); - if (r) { - dev_err(dssdev->dev, "failed to set VC_ID\n"); - goto err_vc_id; - } - - r = sysfs_create_group(&dssdev->dev->kobj, &taal_attr_group); - if (r) { - dev_err(dssdev->dev, "failed to create sysfs files\n"); - goto err_vc_id; - } - - return 0; - -err_vc_id: - omap_dsi_release_vc(dssdev, td->channel); -err_req_vc: - if (bldev != NULL) - backlight_device_unregister(bldev); -err_bl: - destroy_workqueue(td->workqueue); - return r; -} - -static void __exit taal_remove(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - struct backlight_device *bldev; - - dev_dbg(dssdev->dev, "remove\n"); - - sysfs_remove_group(&dssdev->dev->kobj, &taal_attr_group); - omap_dsi_release_vc(dssdev, td->channel); - - bldev = td->bldev; - if (bldev != NULL) { - bldev->props.power = FB_BLANK_POWERDOWN; - taal_bl_update_status(bldev); - backlight_device_unregister(bldev); - } - - taal_cancel_ulps_work(dssdev); - taal_cancel_esd_work(dssdev); - destroy_workqueue(td->workqueue); - - /* reset, to be sure that the panel is in a valid state */ - taal_hw_reset(dssdev); -} - -static int taal_power_on(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - u8 id1, id2, id3; - int r; - struct omap_dss_dsi_config dsi_config = { - .mode = OMAP_DSS_DSI_CMD_MODE, - .pixel_format = OMAP_DSS_DSI_FMT_RGB888, - .timings = &dssdev->panel.timings, - .hs_clk_min = 150000000, - .hs_clk_max = 300000000, - .lp_clk_min = 7000000, - .lp_clk_max = 10000000, - }; - - r = omapdss_dsi_configure_pins(dssdev, &td->pin_config); - if (r) { - dev_err(dssdev->dev, "failed to configure DSI pins\n"); - goto err0; - }; - - r = omapdss_dsi_set_config(dssdev, &dsi_config); - if (r) { - dev_err(dssdev->dev, "failed to configure DSI\n"); - goto err0; - } - - r = omapdss_dsi_display_enable(dssdev); - if (r) { - dev_err(dssdev->dev, "failed to enable DSI\n"); - goto err0; - } - - taal_hw_reset(dssdev); - - omapdss_dsi_vc_enable_hs(dssdev, td->channel, false); - - r = taal_sleep_out(td); - if (r) - goto err; - - r = taal_get_id(td, &id1, &id2, &id3); - if (r) - goto err; - - /* on early Taal revisions CABC is broken */ - if (id2 == 0x00 || id2 == 0xff || id2 == 0x81) - td->cabc_broken = true; - - r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff); - if (r) - goto err; - - r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY, - (1<<2) | (1<<5)); /* BL | BCTRL */ - if (r) - goto err; - - r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT, - MIPI_DCS_PIXEL_FMT_24BIT); - if (r) - goto err; - - if (!td->cabc_broken) { - r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode); - if (r) - goto err; - } - - r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON); - if (r) - goto err; - - r = _taal_enable_te(dssdev, td->te_enabled); - if (r) - goto err; - - r = dsi_enable_video_output(dssdev, td->channel); - if (r) - goto err; - - td->enabled = 1; - - if (!td->intro_printed) { - dev_info(dssdev->dev, "panel revision %02x.%02x.%02x\n", - id1, id2, id3); - if (td->cabc_broken) - dev_info(dssdev->dev, - "old Taal version, CABC disabled\n"); - td->intro_printed = true; - } - - omapdss_dsi_vc_enable_hs(dssdev, td->channel, true); - - return 0; -err: - dev_err(dssdev->dev, "error while enabling panel, issuing HW reset\n"); - - taal_hw_reset(dssdev); - - omapdss_dsi_display_disable(dssdev, true, false); -err0: - return r; -} - -static void taal_power_off(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - dsi_disable_video_output(dssdev, td->channel); - - r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF); - if (!r) - r = taal_sleep_in(td); - - if (r) { - dev_err(dssdev->dev, - "error disabling panel, issuing HW reset\n"); - taal_hw_reset(dssdev); - } - - omapdss_dsi_display_disable(dssdev, true, false); - - td->enabled = 0; -} - -static int taal_panel_reset(struct omap_dss_device *dssdev) -{ - dev_err(dssdev->dev, "performing LCD reset\n"); - - taal_power_off(dssdev); - taal_hw_reset(dssdev); - return taal_power_on(dssdev); -} - -static int taal_enable(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - dev_dbg(dssdev->dev, "enable\n"); - - mutex_lock(&td->lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { - r = -EINVAL; - goto err; - } - - dsi_bus_lock(dssdev); - - r = taal_power_on(dssdev); - - dsi_bus_unlock(dssdev); - - if (r) - goto err; - - taal_queue_esd_work(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - mutex_unlock(&td->lock); - - return 0; -err: - dev_dbg(dssdev->dev, "enable failed\n"); - mutex_unlock(&td->lock); - return r; -} - -static void taal_disable(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - dev_dbg(dssdev->dev, "disable\n"); - - mutex_lock(&td->lock); - - taal_cancel_ulps_work(dssdev); - taal_cancel_esd_work(dssdev); - - dsi_bus_lock(dssdev); - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { - int r; - - r = taal_wake_up(dssdev); - if (!r) - taal_power_off(dssdev); - } - - dsi_bus_unlock(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - - mutex_unlock(&td->lock); -} - -static void taal_framedone_cb(int err, void *data) -{ - struct omap_dss_device *dssdev = data; - dev_dbg(dssdev->dev, "framedone, err %d\n", err); - dsi_bus_unlock(dssdev); -} - -static irqreturn_t taal_te_isr(int irq, void *data) -{ - struct omap_dss_device *dssdev = data; - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int old; - int r; - - old = atomic_cmpxchg(&td->do_update, 1, 0); - - if (old) { - cancel_delayed_work(&td->te_timeout_work); - - r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb, - dssdev); - if (r) - goto err; - } - - return IRQ_HANDLED; -err: - dev_err(dssdev->dev, "start update failed\n"); - dsi_bus_unlock(dssdev); - return IRQ_HANDLED; -} - -static void taal_te_timeout_work_callback(struct work_struct *work) -{ - struct taal_data *td = container_of(work, struct taal_data, - te_timeout_work.work); - struct omap_dss_device *dssdev = td->dssdev; - - dev_err(dssdev->dev, "TE not received for 250ms!\n"); - - atomic_set(&td->do_update, 0); - dsi_bus_unlock(dssdev); -} - -static int taal_update(struct omap_dss_device *dssdev, - u16 x, u16 y, u16 w, u16 h) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - dev_dbg(dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h); - - mutex_lock(&td->lock); - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (r) - goto err; - - if (!td->enabled) { - r = 0; - goto err; - } - - /* XXX no need to send this every frame, but dsi break if not done */ - r = taal_set_update_window(td, 0, 0, - dssdev->panel.timings.x_res, - dssdev->panel.timings.y_res); - if (r) - goto err; - - if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) { - schedule_delayed_work(&td->te_timeout_work, - msecs_to_jiffies(250)); - atomic_set(&td->do_update, 1); - } else { - r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb, - dssdev); - if (r) - goto err; - } - - /* note: no bus_unlock here. unlock is in framedone_cb */ - mutex_unlock(&td->lock); - return 0; -err: - dsi_bus_unlock(dssdev); - mutex_unlock(&td->lock); - return r; -} - -static int taal_sync(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - dev_dbg(dssdev->dev, "sync\n"); - - mutex_lock(&td->lock); - dsi_bus_lock(dssdev); - dsi_bus_unlock(dssdev); - mutex_unlock(&td->lock); - - dev_dbg(dssdev->dev, "sync done\n"); - - return 0; -} - -static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - if (enable) - r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0); - else - r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF); - - if (!gpio_is_valid(td->ext_te_gpio)) - omapdss_dsi_enable_te(dssdev, enable); - - /* possible panel bug */ - msleep(100); - - return r; -} - -static int taal_enable_te(struct omap_dss_device *dssdev, bool enable) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - mutex_lock(&td->lock); - - if (td->te_enabled == enable) - goto end; - - dsi_bus_lock(dssdev); - - if (td->enabled) { - r = taal_wake_up(dssdev); - if (r) - goto err; - - r = _taal_enable_te(dssdev, enable); - if (r) - goto err; - } - - td->te_enabled = enable; - - dsi_bus_unlock(dssdev); -end: - mutex_unlock(&td->lock); - - return 0; -err: - dsi_bus_unlock(dssdev); - mutex_unlock(&td->lock); - - return r; -} - -static int taal_get_te(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - int r; - - mutex_lock(&td->lock); - r = td->te_enabled; - mutex_unlock(&td->lock); - - return r; -} - -static int taal_run_test(struct omap_dss_device *dssdev, int test_num) -{ - struct taal_data *td = dev_get_drvdata(dssdev->dev); - u8 id1, id2, id3; - int r; - - mutex_lock(&td->lock); - - if (!td->enabled) { - r = -ENODEV; - goto err1; - } - - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (r) - goto err2; - - r = taal_dcs_read_1(td, DCS_GET_ID1, &id1); - if (r) - goto err2; - r = taal_dcs_read_1(td, DCS_GET_ID2, &id2); - if (r) - goto err2; - r = taal_dcs_read_1(td, DCS_GET_ID3, &id3); - if (r) - goto err2; - - dsi_bus_unlock(dssdev); - mutex_unlock(&td->lock); - return 0; -err2: - dsi_bus_unlock(dssdev); -err1: - mutex_unlock(&td->lock); - return r; -} - -static int taal_memory_read(struct omap_dss_device *dssdev, - void *buf, size_t size, - u16 x, u16 y, u16 w, u16 h) -{ - int r; - int first = 1; - int plen; - unsigned buf_used = 0; - struct taal_data *td = dev_get_drvdata(dssdev->dev); - - if (size < w * h * 3) - return -ENOMEM; - - mutex_lock(&td->lock); - - if (!td->enabled) { - r = -ENODEV; - goto err1; - } - - size = min(w * h * 3, - dssdev->panel.timings.x_res * - dssdev->panel.timings.y_res * 3); - - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (r) - goto err2; - - /* plen 1 or 2 goes into short packet. until checksum error is fixed, - * use short packets. plen 32 works, but bigger packets seem to cause - * an error. */ - if (size % 2) - plen = 1; - else - plen = 2; - - taal_set_update_window(td, x, y, w, h); - - r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen); - if (r) - goto err2; - - while (buf_used < size) { - u8 dcs_cmd = first ? 0x2e : 0x3e; - first = 0; - - r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd, - buf + buf_used, size - buf_used); - - if (r < 0) { - dev_err(dssdev->dev, "read error\n"); - goto err3; - } - - buf_used += r; - - if (r < plen) { - dev_err(dssdev->dev, "short read\n"); - break; - } - - if (signal_pending(current)) { - dev_err(dssdev->dev, "signal pending, " - "aborting memory read\n"); - r = -ERESTARTSYS; - goto err3; - } - } - - r = buf_used; - -err3: - dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1); -err2: - dsi_bus_unlock(dssdev); -err1: - mutex_unlock(&td->lock); - return r; -} - -static void taal_ulps_work(struct work_struct *work) -{ - struct taal_data *td = container_of(work, struct taal_data, - ulps_work.work); - struct omap_dss_device *dssdev = td->dssdev; - - mutex_lock(&td->lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !td->enabled) { - mutex_unlock(&td->lock); - return; - } - - dsi_bus_lock(dssdev); - - taal_enter_ulps(dssdev); - - dsi_bus_unlock(dssdev); - mutex_unlock(&td->lock); -} - -static void taal_esd_work(struct work_struct *work) -{ - struct taal_data *td = container_of(work, struct taal_data, - esd_work.work); - struct omap_dss_device *dssdev = td->dssdev; - u8 state1, state2; - int r; - - mutex_lock(&td->lock); - - if (!td->enabled) { - mutex_unlock(&td->lock); - return; - } - - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (r) { - dev_err(dssdev->dev, "failed to exit ULPS\n"); - goto err; - } - - r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1); - if (r) { - dev_err(dssdev->dev, "failed to read Taal status\n"); - goto err; - } - - /* Run self diagnostics */ - r = taal_sleep_out(td); - if (r) { - dev_err(dssdev->dev, "failed to run Taal self-diagnostics\n"); - goto err; - } - - r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2); - if (r) { - dev_err(dssdev->dev, "failed to read Taal status\n"); - goto err; - } - - /* Each sleep out command will trigger a self diagnostic and flip - * Bit6 if the test passes. - */ - if (!((state1 ^ state2) & (1 << 6))) { - dev_err(dssdev->dev, "LCD self diagnostics failed\n"); - goto err; - } - /* Self-diagnostics result is also shown on TE GPIO line. We need - * to re-enable TE after self diagnostics */ - if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) { - r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0); - if (r) - goto err; - } - - dsi_bus_unlock(dssdev); - - taal_queue_esd_work(dssdev); - - mutex_unlock(&td->lock); - return; -err: - dev_err(dssdev->dev, "performing LCD reset\n"); - - taal_panel_reset(dssdev); - - dsi_bus_unlock(dssdev); - - taal_queue_esd_work(dssdev); - - mutex_unlock(&td->lock); -} - -static struct omap_dss_driver taal_driver = { - .probe = taal_probe, - .remove = __exit_p(taal_remove), - - .enable = taal_enable, - .disable = taal_disable, - - .update = taal_update, - .sync = taal_sync, - - .get_resolution = taal_get_resolution, - .get_recommended_bpp = omapdss_default_get_recommended_bpp, - - .enable_te = taal_enable_te, - .get_te = taal_get_te, - - .run_test = taal_run_test, - .memory_read = taal_memory_read, - - .driver = { - .name = "taal", - .owner = THIS_MODULE, - }, -}; - -static int __init taal_init(void) -{ - omap_dss_register_driver(&taal_driver); - - return 0; -} - -static void __exit taal_exit(void) -{ - omap_dss_unregister_driver(&taal_driver); -} - -module_init(taal_init); -module_exit(taal_exit); - -MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); -MODULE_DESCRIPTION("Taal Driver"); -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 @@ -/* - * TFP410 DPI-to-DVI chip - * - * Copyright (C) 2011 Texas Instruments Inc - * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/module.h> -#include <linux/slab.h> -#include <video/omapdss.h> -#include <linux/i2c.h> -#include <linux/gpio.h> -#include <drm/drm_edid.h> - -#include <video/omap-panel-data.h> - -static const struct omap_video_timings tfp410_default_timings = { - .x_res = 640, - .y_res = 480, - - .pixel_clock = 23500, - - .hfp = 48, - .hsw = 32, - .hbp = 80, - - .vfp = 3, - .vsw = 4, - .vbp = 7, - - .vsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .hsync_level = OMAPDSS_SIG_ACTIVE_HIGH, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, -}; - -struct panel_drv_data { - struct omap_dss_device *dssdev; - - struct mutex lock; - - int pd_gpio; - - struct i2c_adapter *i2c_adapter; -}; - -static int tfp410_power_on(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - int r; - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); - - r = omapdss_dpi_display_enable(dssdev); - if (r) - goto err0; - - if (gpio_is_valid(ddata->pd_gpio)) - gpio_set_value_cansleep(ddata->pd_gpio, 1); - - return 0; -err0: - return r; -} - -static void tfp410_power_off(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - if (gpio_is_valid(ddata->pd_gpio)) - gpio_set_value_cansleep(ddata->pd_gpio, 0); - - omapdss_dpi_display_disable(dssdev); -} - -static int tfp410_probe(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata; - int r; - int i2c_bus_num; - - ddata = devm_kzalloc(dssdev->dev, sizeof(*ddata), GFP_KERNEL); - if (!ddata) - return -ENOMEM; - - dssdev->panel.timings = tfp410_default_timings; - - ddata->dssdev = dssdev; - mutex_init(&ddata->lock); - - if (dssdev->data) { - struct tfp410_platform_data *pdata = dssdev->data; - - ddata->pd_gpio = pdata->power_down_gpio; - i2c_bus_num = pdata->i2c_bus_num; - } else { - ddata->pd_gpio = -1; - i2c_bus_num = -1; - } - - if (gpio_is_valid(ddata->pd_gpio)) { - r = devm_gpio_request_one(dssdev->dev, ddata->pd_gpio, - GPIOF_OUT_INIT_LOW, "tfp410 pd"); - if (r) { - dev_err(dssdev->dev, "Failed to request PD GPIO %d\n", - ddata->pd_gpio); - return r; - } - } - - if (i2c_bus_num != -1) { - struct i2c_adapter *adapter; - - adapter = i2c_get_adapter(i2c_bus_num); - if (!adapter) { - dev_err(dssdev->dev, "Failed to get I2C adapter, bus %d\n", - i2c_bus_num); - return -EPROBE_DEFER; - } - - ddata->i2c_adapter = adapter; - } - - dev_set_drvdata(dssdev->dev, ddata); - - return 0; -} - -static void __exit tfp410_remove(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - - mutex_lock(&ddata->lock); - - if (ddata->i2c_adapter) - i2c_put_adapter(ddata->i2c_adapter); - - dev_set_drvdata(dssdev->dev, NULL); - - mutex_unlock(&ddata->lock); -} - -static int tfp410_enable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - int r; - - mutex_lock(&ddata->lock); - - r = tfp410_power_on(dssdev); - if (r == 0) - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - mutex_unlock(&ddata->lock); - - return r; -} - -static void tfp410_disable(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - - mutex_lock(&ddata->lock); - - tfp410_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - - mutex_unlock(&ddata->lock); -} - -static void tfp410_set_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - - mutex_lock(&ddata->lock); - omapdss_dpi_set_timings(dssdev, timings); - dssdev->panel.timings = *timings; - mutex_unlock(&ddata->lock); -} - -static void tfp410_get_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - - mutex_lock(&ddata->lock); - *timings = dssdev->panel.timings; - mutex_unlock(&ddata->lock); -} - -static int tfp410_check_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - int r; - - mutex_lock(&ddata->lock); - r = dpi_check_timings(dssdev, timings); - mutex_unlock(&ddata->lock); - - return r; -} - - -static int tfp410_ddc_read(struct i2c_adapter *adapter, - unsigned char *buf, u16 count, u8 offset) -{ - int r, retries; - - for (retries = 3; retries > 0; retries--) { - struct i2c_msg msgs[] = { - { - .addr = DDC_ADDR, - .flags = 0, - .len = 1, - .buf = &offset, - }, { - .addr = DDC_ADDR, - .flags = I2C_M_RD, - .len = count, - .buf = buf, - } - }; - - r = i2c_transfer(adapter, msgs, 2); - if (r == 2) - return 0; - - if (r != -EAGAIN) - break; - } - - return r < 0 ? r : -EIO; -} - -static int tfp410_read_edid(struct omap_dss_device *dssdev, - u8 *edid, int len) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - int r, l, bytes_read; - - mutex_lock(&ddata->lock); - - if (!ddata->i2c_adapter) { - r = -ENODEV; - goto err; - } - - l = min(EDID_LENGTH, len); - r = tfp410_ddc_read(ddata->i2c_adapter, edid, l, 0); - if (r) - goto err; - - bytes_read = l; - - /* if there are extensions, read second block */ - if (len > EDID_LENGTH && edid[0x7e] > 0) { - l = min(EDID_LENGTH, len - EDID_LENGTH); - - r = tfp410_ddc_read(ddata->i2c_adapter, edid + EDID_LENGTH, - l, EDID_LENGTH); - if (r) - goto err; - - bytes_read += l; - } - - mutex_unlock(&ddata->lock); - - return bytes_read; - -err: - mutex_unlock(&ddata->lock); - return r; -} - -static bool tfp410_detect(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(dssdev->dev); - unsigned char out; - int r; - - mutex_lock(&ddata->lock); - - if (!ddata->i2c_adapter) - goto out; - - r = tfp410_ddc_read(ddata->i2c_adapter, &out, 1, 0); - - mutex_unlock(&ddata->lock); - - return r == 0; - -out: - mutex_unlock(&ddata->lock); - return true; -} - -static struct omap_dss_driver tfp410_driver = { - .probe = tfp410_probe, - .remove = __exit_p(tfp410_remove), - - .enable = tfp410_enable, - .disable = tfp410_disable, - - .set_timings = tfp410_set_timings, - .get_timings = tfp410_get_timings, - .check_timings = tfp410_check_timings, - - .read_edid = tfp410_read_edid, - .detect = tfp410_detect, - - .driver = { - .name = "tfp410", - .owner = THIS_MODULE, - }, -}; - -static int __init tfp410_init(void) -{ - return omap_dss_register_driver(&tfp410_driver); -} - -static void __exit tfp410_exit(void) -{ - omap_dss_unregister_driver(&tfp410_driver); -} - -module_init(tfp410_init); -module_exit(tfp410_exit); -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 @@ -/* - * LCD panel driver for TPO TD043MTEA1 - * - * Author: Gražvydas Ignotas <notasas@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/spi/spi.h> -#include <linux/regulator/consumer.h> -#include <linux/gpio.h> -#include <linux/err.h> -#include <linux/slab.h> - -#include <video/omapdss.h> -#include <video/omap-panel-data.h> - -#define TPO_R02_MODE(x) ((x) & 7) -#define TPO_R02_MODE_800x480 7 -#define TPO_R02_NCLK_RISING BIT(3) -#define TPO_R02_HSYNC_HIGH BIT(4) -#define TPO_R02_VSYNC_HIGH BIT(5) - -#define TPO_R03_NSTANDBY BIT(0) -#define TPO_R03_EN_CP_CLK BIT(1) -#define TPO_R03_EN_VGL_PUMP BIT(2) -#define TPO_R03_EN_PWM BIT(3) -#define TPO_R03_DRIVING_CAP_100 BIT(4) -#define TPO_R03_EN_PRE_CHARGE BIT(6) -#define TPO_R03_SOFTWARE_CTL BIT(7) - -#define TPO_R04_NFLIP_H BIT(0) -#define TPO_R04_NFLIP_V BIT(1) -#define TPO_R04_CP_CLK_FREQ_1H BIT(2) -#define TPO_R04_VGL_FREQ_1H BIT(4) - -#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \ - TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \ - TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \ - TPO_R03_SOFTWARE_CTL) - -#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \ - TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) - -static const u16 tpo_td043_def_gamma[12] = { - 105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023 -}; - -struct tpo_td043_device { - struct spi_device *spi; - struct regulator *vcc_reg; - int nreset_gpio; - u16 gamma[12]; - u32 mode; - u32 hmirror:1; - u32 vmirror:1; - u32 powered_on:1; - u32 spi_suspended:1; - u32 power_on_resume:1; -}; - -/* used to pass spi_device from SPI to DSS portion of the driver */ -static struct tpo_td043_device *g_tpo_td043; - -static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) -{ - struct spi_message m; - struct spi_transfer xfer; - u16 w; - int r; - - spi_message_init(&m); - - memset(&xfer, 0, sizeof(xfer)); - - w = ((u16)addr << 10) | (1 << 8) | data; - xfer.tx_buf = &w; - xfer.bits_per_word = 16; - xfer.len = 2; - spi_message_add_tail(&xfer, &m); - - r = spi_sync(spi, &m); - if (r < 0) - dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r); - return r; -} - -static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12]) -{ - u8 i, val; - - /* gamma bits [9:8] */ - for (val = i = 0; i < 4; i++) - val |= (gamma[i] & 0x300) >> ((i + 1) * 2); - tpo_td043_write(spi, 0x11, val); - - for (val = i = 0; i < 4; i++) - val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2); - tpo_td043_write(spi, 0x12, val); - - for (val = i = 0; i < 4; i++) - val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2); - tpo_td043_write(spi, 0x13, val); - - /* gamma bits [7:0] */ - for (val = i = 0; i < 12; i++) - tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff); -} - -static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) -{ - u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \ - TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H; - if (h) - reg4 &= ~TPO_R04_NFLIP_H; - if (v) - reg4 &= ~TPO_R04_NFLIP_V; - - return tpo_td043_write(spi, 4, reg4); -} - -static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); - - tpo_td043->hmirror = enable; - return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, - tpo_td043->vmirror); -} - -static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); - - return tpo_td043->hmirror; -} - -static ssize_t tpo_td043_vmirror_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror); -} - -static ssize_t tpo_td043_vmirror_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - int val; - int ret; - - ret = kstrtoint(buf, 0, &val); - if (ret < 0) - return ret; - - val = !!val; - - ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val); - if (ret < 0) - return ret; - - tpo_td043->vmirror = val; - - return count; -} - -static ssize_t tpo_td043_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - - return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode); -} - -static ssize_t tpo_td043_mode_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - long val; - int ret; - - ret = kstrtol(buf, 0, &val); - if (ret != 0 || val & ~7) - return -EINVAL; - - tpo_td043->mode = val; - - val |= TPO_R02_NCLK_RISING; - tpo_td043_write(tpo_td043->spi, 2, val); - - return count; -} - -static ssize_t tpo_td043_gamma_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - ssize_t len = 0; - int ret; - int i; - - for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) { - ret = snprintf(buf + len, PAGE_SIZE - len, "%u ", - tpo_td043->gamma[i]); - if (ret < 0) - return ret; - len += ret; - } - buf[len - 1] = '\n'; - - return len; -} - -static ssize_t tpo_td043_gamma_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - unsigned int g[12]; - int ret; - int i; - - ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u", - &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], - &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); - - if (ret != 12) - return -EINVAL; - - for (i = 0; i < 12; i++) - tpo_td043->gamma[i] = g[i]; - - tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); - - return count; -} - -static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR, - tpo_td043_vmirror_show, tpo_td043_vmirror_store); -static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, - tpo_td043_mode_show, tpo_td043_mode_store); -static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR, - tpo_td043_gamma_show, tpo_td043_gamma_store); - -static struct attribute *tpo_td043_attrs[] = { - &dev_attr_vmirror.attr, - &dev_attr_mode.attr, - &dev_attr_gamma.attr, - NULL, -}; - -static struct attribute_group tpo_td043_attr_group = { - .attrs = tpo_td043_attrs, -}; - -static const struct omap_video_timings tpo_td043_timings = { - .x_res = 800, - .y_res = 480, - - .pixel_clock = 36000, - - .hsw = 1, - .hfp = 68, - .hbp = 214, - - .vsw = 1, - .vfp = 39, - .vbp = 34, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .data_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE, - .de_level = OMAPDSS_SIG_ACTIVE_HIGH, - .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, -}; - -static inline struct panel_tpo_td043_data -*get_panel_data(const struct omap_dss_device *dssdev) -{ - return (struct panel_tpo_td043_data *) dssdev->data; -} - -static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) -{ - int r; - - if (tpo_td043->powered_on) - return 0; - - r = regulator_enable(tpo_td043->vcc_reg); - if (r != 0) - return r; - - /* wait for panel to stabilize */ - msleep(160); - - if (gpio_is_valid(tpo_td043->nreset_gpio)) - gpio_set_value(tpo_td043->nreset_gpio, 1); - - tpo_td043_write(tpo_td043->spi, 2, - TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING); - tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL); - tpo_td043_write(tpo_td043->spi, 0x20, 0xf0); - tpo_td043_write(tpo_td043->spi, 0x21, 0xf0); - tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, - tpo_td043->vmirror); - tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); - - tpo_td043->powered_on = 1; - return 0; -} - -static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043) -{ - if (!tpo_td043->powered_on) - return; - - tpo_td043_write(tpo_td043->spi, 3, - TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); - - if (gpio_is_valid(tpo_td043->nreset_gpio)) - gpio_set_value(tpo_td043->nreset_gpio, 0); - - /* wait for at least 2 vsyncs before cutting off power */ - msleep(50); - - tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY); - - regulator_disable(tpo_td043->vcc_reg); - - tpo_td043->powered_on = 0; -} - -static int tpo_td043_enable_dss(struct omap_dss_device *dssdev) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); - int r; - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) - return 0; - - omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings); - omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines); - - r = omapdss_dpi_display_enable(dssdev); - if (r) - goto err0; - - /* - * If we are resuming from system suspend, SPI clocks might not be - * enabled yet, so we'll program the LCD from SPI PM resume callback. - */ - if (!tpo_td043->spi_suspended) { - r = tpo_td043_power_on(tpo_td043); - if (r) - goto err1; - } - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - return 0; -err1: - omapdss_dpi_display_disable(dssdev); -err0: - return r; -} - -static void tpo_td043_disable_dss(struct omap_dss_device *dssdev) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return; - - omapdss_dpi_display_disable(dssdev); - - if (!tpo_td043->spi_suspended) - tpo_td043_power_off(tpo_td043); -} - -static int tpo_td043_enable(struct omap_dss_device *dssdev) -{ - dev_dbg(dssdev->dev, "enable\n"); - - return tpo_td043_enable_dss(dssdev); -} - -static void tpo_td043_disable(struct omap_dss_device *dssdev) -{ - dev_dbg(dssdev->dev, "disable\n"); - - tpo_td043_disable_dss(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -} - -static int tpo_td043_probe(struct omap_dss_device *dssdev) -{ - struct tpo_td043_device *tpo_td043 = g_tpo_td043; - struct panel_tpo_td043_data *pdata = get_panel_data(dssdev); - int ret = 0; - - dev_dbg(dssdev->dev, "probe\n"); - - if (tpo_td043 == NULL) { - dev_err(dssdev->dev, "missing tpo_td043_device\n"); - return -ENODEV; - } - - if (!pdata) - return -EINVAL; - - tpo_td043->nreset_gpio = pdata->nreset_gpio; - - dssdev->panel.timings = tpo_td043_timings; - dssdev->ctrl.pixel_size = 24; - - tpo_td043->mode = TPO_R02_MODE_800x480; - memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma)); - - tpo_td043->vcc_reg = regulator_get(dssdev->dev, "vcc"); - if (IS_ERR(tpo_td043->vcc_reg)) { - dev_err(dssdev->dev, "failed to get LCD VCC regulator\n"); - ret = PTR_ERR(tpo_td043->vcc_reg); - goto fail_regulator; - } - - if (gpio_is_valid(tpo_td043->nreset_gpio)) { - ret = devm_gpio_request_one(dssdev->dev, - tpo_td043->nreset_gpio, GPIOF_OUT_INIT_LOW, - "lcd reset"); - if (ret < 0) { - dev_err(dssdev->dev, "couldn't request reset GPIO\n"); - goto fail_gpio_req; - } - } - - ret = sysfs_create_group(&dssdev->dev->kobj, &tpo_td043_attr_group); - if (ret) - dev_warn(dssdev->dev, "failed to create sysfs files\n"); - - dev_set_drvdata(dssdev->dev, tpo_td043); - - return 0; - -fail_gpio_req: - regulator_put(tpo_td043->vcc_reg); -fail_regulator: - kfree(tpo_td043); - return ret; -} - -static void tpo_td043_remove(struct omap_dss_device *dssdev) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dssdev->dev); - - dev_dbg(dssdev->dev, "remove\n"); - - sysfs_remove_group(&dssdev->dev->kobj, &tpo_td043_attr_group); - regulator_put(tpo_td043->vcc_reg); -} - -static void tpo_td043_set_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - omapdss_dpi_set_timings(dssdev, timings); - - dssdev->panel.timings = *timings; -} - -static int tpo_td043_check_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - return dpi_check_timings(dssdev, timings); -} - -static struct omap_dss_driver tpo_td043_driver = { - .probe = tpo_td043_probe, - .remove = tpo_td043_remove, - - .enable = tpo_td043_enable, - .disable = tpo_td043_disable, - .set_mirror = tpo_td043_set_hmirror, - .get_mirror = tpo_td043_get_hmirror, - - .set_timings = tpo_td043_set_timings, - .check_timings = tpo_td043_check_timings, - - .driver = { - .name = "tpo_td043mtea1_panel", - .owner = THIS_MODULE, - }, -}; - -static int tpo_td043_spi_probe(struct spi_device *spi) -{ - struct omap_dss_device *dssdev = spi->dev.platform_data; - struct tpo_td043_device *tpo_td043; - int ret; - - if (dssdev == NULL) { - dev_err(&spi->dev, "missing dssdev\n"); - return -ENODEV; - } - - if (g_tpo_td043 != NULL) - return -EBUSY; - - spi->bits_per_word = 16; - spi->mode = SPI_MODE_0; - - ret = spi_setup(spi); - if (ret < 0) { - dev_err(&spi->dev, "spi_setup failed: %d\n", ret); - return ret; - } - - tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL); - if (tpo_td043 == NULL) - return -ENOMEM; - - tpo_td043->spi = spi; - dev_set_drvdata(&spi->dev, tpo_td043); - g_tpo_td043 = tpo_td043; - - omap_dss_register_driver(&tpo_td043_driver); - - return 0; -} - -static int tpo_td043_spi_remove(struct spi_device *spi) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev); - - omap_dss_unregister_driver(&tpo_td043_driver); - kfree(tpo_td043); - g_tpo_td043 = NULL; - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int tpo_td043_spi_suspend(struct device *dev) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - - dev_dbg(dev, "tpo_td043_spi_suspend, tpo %p\n", tpo_td043); - - tpo_td043->power_on_resume = tpo_td043->powered_on; - tpo_td043_power_off(tpo_td043); - tpo_td043->spi_suspended = 1; - - return 0; -} - -static int tpo_td043_spi_resume(struct device *dev) -{ - struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); - int ret; - - dev_dbg(dev, "tpo_td043_spi_resume\n"); - - if (tpo_td043->power_on_resume) { - ret = tpo_td043_power_on(tpo_td043); - if (ret) - return ret; - } - tpo_td043->spi_suspended = 0; - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm, - tpo_td043_spi_suspend, tpo_td043_spi_resume); - -static struct spi_driver tpo_td043_spi_driver = { - .driver = { - .name = "tpo_td043mtea1_panel_spi", - .owner = THIS_MODULE, - .pm = &tpo_td043_spi_pm, - }, - .probe = tpo_td043_spi_probe, - .remove = tpo_td043_spi_remove, -}; - -module_spi_driver(tpo_td043_spi_driver); - -MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>"); -MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); -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 config OMAP2_DSS_RFBI bool "RFBI support" + depends on BROKEN default n help 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 \ dispc-compat.o display-sysfs.o omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o -omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o +omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o -omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ - hdmi_panel.o ti_hdmi_4xxx_ip.o +omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o ti_hdmi_4xxx_ip.o 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 if (dssdev == NULL) return NULL; - while (dssdev->device) - dssdev = dssdev->device; + while (dssdev->dst) + dssdev = dssdev->dst; if (dssdev->driver) 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 @@ static struct { struct platform_device *pdev; - struct regulator *vdds_dsi_reg; - struct regulator *vdds_sdi_reg; - const char *default_display_name; } core; @@ -79,36 +76,6 @@ struct platform_device *dss_get_core_pdev(void) return core.pdev; } -/* REGULATORS */ - -struct regulator *dss_get_vdds_dsi(void) -{ - struct regulator *reg; - - if (core.vdds_dsi_reg != NULL) - return core.vdds_dsi_reg; - - reg = devm_regulator_get(&core.pdev->dev, "vdds_dsi"); - if (!IS_ERR(reg)) - core.vdds_dsi_reg = reg; - - return reg; -} - -struct regulator *dss_get_vdds_sdi(void) -{ - struct regulator *reg; - - if (core.vdds_sdi_reg != NULL) - return core.vdds_sdi_reg; - - reg = devm_regulator_get(&core.pdev->dev, "vdds_sdi"); - if (!IS_ERR(reg)) - core.vdds_sdi_reg = reg; - - return reg; -} - int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask) { 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 *)) d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, write, &dss_debug_fops); - return PTR_RET(d); + return PTR_ERR_OR_ZERO(d); } #else /* CONFIG_OMAP2_DSS_DEBUGFS */ static inline int dss_initialize_debugfs(void) @@ -281,235 +248,6 @@ static struct platform_driver omap_dss_driver = { }, }; -/* BUS */ -static int dss_bus_match(struct device *dev, struct device_driver *driver) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - - DSSDBG("bus_match. dev %s/%s, drv %s\n", - dev_name(dev), dssdev->driver_name, driver->name); - - return strcmp(dssdev->driver_name, driver->name) == 0; -} - -static struct bus_type dss_bus_type = { - .name = "omapdss", - .match = dss_bus_match, -}; - -static void dss_bus_release(struct device *dev) -{ - DSSDBG("bus_release\n"); -} - -static struct device dss_bus = { - .release = dss_bus_release, -}; - -struct bus_type *dss_get_bus(void) -{ - return &dss_bus_type; -} - -/* DRIVER */ -static int dss_driver_probe(struct device *dev) -{ - int r; - struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); - struct omap_dss_device *dssdev = to_dss_device(dev); - - DSSDBG("driver_probe: dev %s/%s, drv %s\n", - dev_name(dev), dssdev->driver_name, - dssdrv->driver.name); - - r = dssdrv->probe(dssdev); - - if (r) { - DSSERR("driver probe failed: %d\n", r); - return r; - } - - DSSDBG("probe done for device %s\n", dev_name(dev)); - - dssdev->driver = dssdrv; - - return 0; -} - -static int dss_driver_remove(struct device *dev) -{ - struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); - struct omap_dss_device *dssdev = to_dss_device(dev); - - DSSDBG("driver_remove: dev %s/%s\n", dev_name(dev), - dssdev->driver_name); - - dssdrv->remove(dssdev); - - dssdev->driver = NULL; - - return 0; -} - -static int omapdss_default_connect(struct omap_dss_device *dssdev) -{ - struct omap_dss_device *out; - struct omap_overlay_manager *mgr; - int r; - - out = dssdev->output; - - if (out == NULL) - return -ENODEV; - - mgr = omap_dss_get_overlay_manager(out->dispc_channel); - if (!mgr) - return -ENODEV; - - r = dss_mgr_connect(mgr, out); - if (r) - return r; - - return 0; -} - -static void omapdss_default_disconnect(struct omap_dss_device *dssdev) -{ - struct omap_dss_device *out; - struct omap_overlay_manager *mgr; - - out = dssdev->output; - - if (out == NULL) - return; - - mgr = out->manager; - - if (mgr == NULL) - return; - - dss_mgr_disconnect(mgr, out); -} - -int omap_dss_register_driver(struct omap_dss_driver *dssdriver) -{ - dssdriver->driver.bus = &dss_bus_type; - dssdriver->driver.probe = dss_driver_probe; - dssdriver->driver.remove = dss_driver_remove; - - if (dssdriver->get_resolution == NULL) - dssdriver->get_resolution = omapdss_default_get_resolution; - if (dssdriver->get_recommended_bpp == NULL) - dssdriver->get_recommended_bpp = - omapdss_default_get_recommended_bpp; - if (dssdriver->get_timings == NULL) - dssdriver->get_timings = omapdss_default_get_timings; - if (dssdriver->connect == NULL) - dssdriver->connect = omapdss_default_connect; - if (dssdriver->disconnect == NULL) - dssdriver->disconnect = omapdss_default_disconnect; - - return driver_register(&dssdriver->driver); -} -EXPORT_SYMBOL(omap_dss_register_driver); - -void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver) -{ - driver_unregister(&dssdriver->driver); -} -EXPORT_SYMBOL(omap_dss_unregister_driver); - -/* DEVICE */ - -static void omap_dss_dev_release(struct device *dev) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - kfree(dssdev); -} - -static int disp_num_counter; - -struct omap_dss_device *dss_alloc_and_init_device(struct device *parent) -{ - struct omap_dss_device *dssdev; - - dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL); - if (!dssdev) - return NULL; - - dssdev->old_dev.bus = &dss_bus_type; - dssdev->old_dev.parent = parent; - dssdev->old_dev.release = omap_dss_dev_release; - dev_set_name(&dssdev->old_dev, "display%d", disp_num_counter++); - - device_initialize(&dssdev->old_dev); - - return dssdev; -} - -int dss_add_device(struct omap_dss_device *dssdev) -{ - dssdev->dev = &dssdev->old_dev; - - omapdss_register_display(dssdev); - return device_add(&dssdev->old_dev); -} - -void dss_put_device(struct omap_dss_device *dssdev) -{ - put_device(&dssdev->old_dev); -} - -void dss_unregister_device(struct omap_dss_device *dssdev) -{ - device_unregister(&dssdev->old_dev); - omapdss_unregister_display(dssdev); -} - -static int dss_unregister_dss_dev(struct device *dev, void *data) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - dss_unregister_device(dssdev); - return 0; -} - -void dss_unregister_child_devices(struct device *parent) -{ - device_for_each_child(parent, NULL, dss_unregister_dss_dev); -} - -void dss_copy_device_pdata(struct omap_dss_device *dst, - const struct omap_dss_device *src) -{ - u8 *d = (u8 *)dst; - u8 *s = (u8 *)src; - size_t dsize = sizeof(struct device); - - memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize); -} - -/* BUS */ -static int __init omap_dss_bus_register(void) -{ - int r; - - r = bus_register(&dss_bus_type); - if (r) { - DSSERR("bus register failed\n"); - return r; - } - - dev_set_name(&dss_bus, "omapdss"); - r = device_register(&dss_bus); - if (r) { - DSSERR("bus driver register failed\n"); - bus_unregister(&dss_bus_type); - return r; - } - - return 0; -} - /* INIT */ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { #ifdef CONFIG_OMAP2_DSS_DSI @@ -555,7 +293,7 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)]; -static int __init omap_dss_register_drivers(void) +static int __init omap_dss_init(void) { int r; int i; @@ -586,6 +324,8 @@ static int __init omap_dss_register_drivers(void) dss_output_drv_loaded[i] = true; } + dss_initialized = true; + return 0; err_dispc: @@ -596,7 +336,7 @@ err_dss: return r; } -static void __exit omap_dss_unregister_drivers(void) +static void __exit omap_dss_exit(void) { int i; @@ -611,64 +351,8 @@ static void __exit omap_dss_unregister_drivers(void) platform_driver_unregister(&omap_dss_driver); } -#ifdef CONFIG_OMAP2_DSS_MODULE -static void omap_dss_bus_unregister(void) -{ - device_unregister(&dss_bus); - - bus_unregister(&dss_bus_type); -} - -static int __init omap_dss_init(void) -{ - int r; - - r = omap_dss_bus_register(); - if (r) - return r; - - r = omap_dss_register_drivers(); - if (r) { - omap_dss_bus_unregister(); - return r; - } - - dss_initialized = true; - - return 0; -} - -static void __exit omap_dss_exit(void) -{ - omap_dss_unregister_drivers(); - - omap_dss_bus_unregister(); -} - module_init(omap_dss_init); module_exit(omap_dss_exit); -#else -static int __init omap_dss_init(void) -{ - return omap_dss_bus_register(); -} - -static int __init omap_dss_init2(void) -{ - int r; - - r = omap_dss_register_drivers(); - if (r) - return r; - - dss_initialized = true; - - return 0; -} - -core_initcall(omap_dss_init); -device_initcall(omap_dss_init2); -#endif MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); 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) dss_mgr_set_lcd_config(mgr, &dpi.mgr_config); } -int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) +static int dpi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &dpi.output; int r; @@ -423,9 +423,8 @@ err_no_reg: mutex_unlock(&dpi.lock); return r; } -EXPORT_SYMBOL(omapdss_dpi_display_enable); -void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) +static void dpi_display_disable(struct omap_dss_device *dssdev) { struct omap_overlay_manager *mgr = dpi.output.manager; @@ -446,9 +445,8 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) mutex_unlock(&dpi.lock); } -EXPORT_SYMBOL(omapdss_dpi_display_disable); -void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, +static void dpi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { DSSDBG("dpi_set_timings\n"); @@ -459,7 +457,6 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev, mutex_unlock(&dpi.lock); } -EXPORT_SYMBOL(omapdss_dpi_set_timings); static void dpi_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) @@ -471,7 +468,7 @@ static void dpi_get_timings(struct omap_dss_device *dssdev, mutex_unlock(&dpi.lock); } -int dpi_check_timings(struct omap_dss_device *dssdev, +static int dpi_check_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { struct omap_overlay_manager *mgr = dpi.output.manager; @@ -510,9 +507,8 @@ int dpi_check_timings(struct omap_dss_device *dssdev, return 0; } -EXPORT_SYMBOL(dpi_check_timings); -void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) +static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) { mutex_lock(&dpi.lock); @@ -520,7 +516,6 @@ void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) mutex_unlock(&dpi.lock); } -EXPORT_SYMBOL(omapdss_dpi_set_data_lines); static int dpi_verify_dsi_pll(struct platform_device *dsidev) { @@ -554,14 +549,10 @@ static int dpi_init_regulator(void) if (dpi.vdds_dsi_reg) return 0; - vdds_dsi = dss_get_vdds_dsi(); - + vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); if (IS_ERR(vdds_dsi)) { - vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); - if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); - return PTR_ERR(vdds_dsi); - } + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(vdds_dsi); } dpi.vdds_dsi_reg = vdds_dsi; @@ -618,76 +609,6 @@ static enum omap_channel dpi_get_channel(void) } } -static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev) -{ - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = omapdss_get_default_display_name(); - struct omap_dss_device *def_dssdev; - int i; - - def_dssdev = NULL; - - for (i = 0; i < pdata->num_devices; ++i) { - struct omap_dss_device *dssdev = pdata->devices[i]; - - if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) - continue; - - if (def_dssdev == NULL) - def_dssdev = dssdev; - - if (def_disp_name != NULL && - strcmp(dssdev->name, def_disp_name) == 0) { - def_dssdev = dssdev; - break; - } - } - - return def_dssdev; -} - -static int dpi_probe_pdata(struct platform_device *dpidev) -{ - struct omap_dss_device *plat_dssdev; - struct omap_dss_device *dssdev; - int r; - - plat_dssdev = dpi_find_dssdev(dpidev); - - if (!plat_dssdev) - return 0; - - r = dpi_init_regulator(); - if (r) - return r; - - dpi_init_pll(); - - dssdev = dss_alloc_and_init_device(&dpidev->dev); - if (!dssdev) - return -ENOMEM; - - dss_copy_device_pdata(dssdev, plat_dssdev); - - r = omapdss_output_set_device(&dpi.output, dssdev); - if (r) { - DSSERR("failed to connect output to new device: %s\n", - dssdev->name); - dss_put_device(dssdev); - return r; - } - - r = dss_add_device(dssdev); - if (r) { - DSSERR("device %s register failed: %d\n", dssdev->name, r); - omapdss_output_unset_device(&dpi.output); - dss_put_device(dssdev); - return r; - } - - return 0; -} - static int dpi_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { @@ -722,9 +643,9 @@ static int dpi_connect(struct omap_dss_device *dssdev, static void dpi_disconnect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - WARN_ON(dst != dssdev->device); + WARN_ON(dst != dssdev->dst); - if (dst != dssdev->device) + if (dst != dssdev->dst) return; omapdss_output_unset_device(dssdev); @@ -737,14 +658,14 @@ static const struct omapdss_dpi_ops dpi_ops = { .connect = dpi_connect, .disconnect = dpi_disconnect, - .enable = omapdss_dpi_display_enable, - .disable = omapdss_dpi_display_disable, + .enable = dpi_display_enable, + .disable = dpi_display_disable, .check_timings = dpi_check_timings, - .set_timings = omapdss_dpi_set_timings, + .set_timings = dpi_set_timings, .get_timings = dpi_get_timings, - .set_data_lines = omapdss_dpi_set_data_lines, + .set_data_lines = dpi_set_data_lines, }; static void dpi_init_output(struct platform_device *pdev) @@ -771,31 +692,17 @@ static void __exit dpi_uninit_output(struct platform_device *pdev) static int omap_dpi_probe(struct platform_device *pdev) { - int r; - dpi.pdev = pdev; mutex_init(&dpi.lock); dpi_init_output(pdev); - if (pdev->dev.platform_data) { - r = dpi_probe_pdata(pdev); - if (r) - goto err_probe; - } - return 0; - -err_probe: - dpi_uninit_output(pdev); - return r; } static int __exit omap_dpi_remove(struct platform_device *pdev) { - dss_unregister_child_devices(&pdev->dev); - dpi_uninit_output(pdev); 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, static void dsi_display_uninit_dispc(struct platform_device *dsidev, struct omap_overlay_manager *mgr); +static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); + #define DSI_MAX_NR_ISRS 2 #define DSI_MAX_NR_LANES 5 @@ -383,16 +385,7 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) { - /* HACK: dssdev can be either the panel device, when using old API, or - * the dsi device itself, when using the new API. So we solve this for - * now by checking the dssdev->id. This will be removed when the old API - * is removed. - */ - if (dssdev->id == OMAP_DSS_OUTPUT_DSI1 || - dssdev->id == OMAP_DSS_OUTPUT_DSI2) - return to_platform_device(dssdev->dev); - - return to_platform_device(dssdev->output->dev); + return to_platform_device(dssdev->dev); } struct platform_device *dsi_get_dsidev_from_id(int module) @@ -432,23 +425,21 @@ static inline u32 dsi_read_reg(struct platform_device *dsidev, return __raw_readl(dsi->base + idx.idx); } -void dsi_bus_lock(struct omap_dss_device *dssdev) +static void dsi_bus_lock(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); down(&dsi->bus_lock); } -EXPORT_SYMBOL(dsi_bus_lock); -void dsi_bus_unlock(struct omap_dss_device *dssdev) +static void dsi_bus_unlock(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); up(&dsi->bus_lock); } -EXPORT_SYMBOL(dsi_bus_unlock); static bool dsi_bus_is_locked(struct platform_device *dsidev) { @@ -2713,7 +2704,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel, return 0; } -void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, +static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, bool enable) { 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, if (dsi->vm_timings.ddr_clk_always_on && enable) dsi_vc_send_null(dssdev, channel); } -EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); static void dsi_vc_flush_long_data(struct platform_device *dsidev, int channel) { @@ -2842,7 +2832,7 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel) return 0; } -int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel) +static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); DECLARE_COMPLETION_ONSTACK(completion); @@ -2885,7 +2875,6 @@ err1: err0: return r; } -EXPORT_SYMBOL(dsi_vc_send_bta_sync); static inline void dsi_vc_write_long_header(struct platform_device *dsidev, 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, return 0; } -int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) +static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, NULL, 0, 0); } -EXPORT_SYMBOL(dsi_vc_send_null); static int dsi_vc_write_nosync_common(struct platform_device *dsidev, 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, return r; } -int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, +static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, u8 *data, int len) { 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, return dsi_vc_write_nosync_common(dsidev, channel, data, len, DSS_DSI_CONTENT_DCS); } -EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); -int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, +static int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, u8 *data, int len) { 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, return dsi_vc_write_nosync_common(dsidev, channel, data, len, DSS_DSI_CONTENT_GENERIC); } -EXPORT_SYMBOL(dsi_vc_generic_write_nosync); static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel, u8 *data, int len, enum dss_dsi_content_type type) @@ -3099,60 +3085,19 @@ err: return r; } -int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data, +static int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data, int len) { return dsi_vc_write_common(dssdev, channel, data, len, DSS_DSI_CONTENT_DCS); } -EXPORT_SYMBOL(dsi_vc_dcs_write); -int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data, +static int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data, int len) { return dsi_vc_write_common(dssdev, channel, data, len, DSS_DSI_CONTENT_GENERIC); } -EXPORT_SYMBOL(dsi_vc_generic_write); - -int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd) -{ - return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1); -} -EXPORT_SYMBOL(dsi_vc_dcs_write_0); - -int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel) -{ - return dsi_vc_generic_write(dssdev, channel, NULL, 0); -} -EXPORT_SYMBOL(dsi_vc_generic_write_0); - -int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, - u8 param) -{ - u8 buf[2]; - buf[0] = dcs_cmd; - buf[1] = param; - return dsi_vc_dcs_write(dssdev, channel, buf, 2); -} -EXPORT_SYMBOL(dsi_vc_dcs_write_1); - -int dsi_vc_generic_write_1(struct omap_dss_device *dssdev, int channel, - u8 param) -{ - return dsi_vc_generic_write(dssdev, channel, ¶m, 1); -} -EXPORT_SYMBOL(dsi_vc_generic_write_1); - -int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel, - u8 param1, u8 param2) -{ - u8 buf[2]; - buf[0] = param1; - buf[1] = param2; - return dsi_vc_generic_write(dssdev, channel, buf, 2); -} -EXPORT_SYMBOL(dsi_vc_generic_write_2); static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev, int channel, u8 dcs_cmd) @@ -3319,7 +3264,7 @@ err: return r; } -int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, +static int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, u8 *buf, int buflen) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -3348,7 +3293,6 @@ err: DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", channel, dcs_cmd); return r; } -EXPORT_SYMBOL(dsi_vc_dcs_read); static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel, 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, return 0; } -int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf, - int buflen) -{ - int r; - - r = dsi_vc_generic_read(dssdev, channel, NULL, 0, buf, buflen); - if (r) { - DSSERR("dsi_vc_generic_read_0(ch %d) failed\n", channel); - return r; - } - - return 0; -} -EXPORT_SYMBOL(dsi_vc_generic_read_0); - -int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param, - u8 *buf, int buflen) -{ - int r; - - r = dsi_vc_generic_read(dssdev, channel, ¶m, 1, buf, buflen); - if (r) { - DSSERR("dsi_vc_generic_read_1(ch %d) failed\n", channel); - return r; - } - - return 0; -} -EXPORT_SYMBOL(dsi_vc_generic_read_1); - -int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel, - u8 param1, u8 param2, u8 *buf, int buflen) -{ - int r; - u8 reqdata[2]; - - reqdata[0] = param1; - reqdata[1] = param2; - - r = dsi_vc_generic_read(dssdev, channel, reqdata, 2, buf, buflen); - if (r) { - DSSERR("dsi_vc_generic_read_2(ch %d) failed\n", channel); - return r; - } - - return 0; -} -EXPORT_SYMBOL(dsi_vc_generic_read_2); - -int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, +static int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, u16 len) { 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, return dsi_vc_send_short(dsidev, channel, MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0); } -EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); static int dsi_enter_ulps(struct platform_device *dsidev) { @@ -4068,7 +3962,7 @@ static void dsi_proto_timings(struct platform_device *dsidev) } } -int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, +static int dsi_configure_pins(struct omap_dss_device *dssdev, const struct omap_dsi_pin_config *pin_cfg) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -4134,9 +4028,8 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, return 0; } -EXPORT_SYMBOL(omapdss_dsi_configure_pins); -int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) +static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); @@ -4206,9 +4099,8 @@ err_pix_fmt: err_init_dispc: return r; } -EXPORT_SYMBOL(dsi_enable_video_output); -void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) +static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 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) dsi_display_uninit_dispc(dsidev, mgr); } -EXPORT_SYMBOL(dsi_disable_video_output); static void dsi_update_screen_dispc(struct platform_device *dsidev) { @@ -4369,7 +4260,7 @@ static void dsi_framedone_irq_callback(void *data) dsi_handle_framedone(dsidev, 0); } -int omap_dsi_update(struct omap_dss_device *dssdev, int channel, +static int dsi_update(struct omap_dss_device *dssdev, int channel, void (*callback)(int, void *), void *data) { 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, return 0; } -EXPORT_SYMBOL(omap_dsi_update); /* Display funcs */ @@ -4589,7 +4479,7 @@ static void dsi_display_uninit_dsi(struct platform_device *dsidev, dsi_pll_uninit(dsidev, disconnect_lanes); } -int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) +static int dsi_display_enable(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); @@ -4625,9 +4515,8 @@ err_get_dsi: DSSDBG("dsi_display_enable FAILED\n"); return r; } -EXPORT_SYMBOL(omapdss_dsi_display_enable); -void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, +static void dsi_display_disable(struct omap_dss_device *dssdev, bool disconnect_lanes, bool enter_ulps) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -4651,9 +4540,8 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, mutex_unlock(&dsi->lock); } -EXPORT_SYMBOL(omapdss_dsi_display_disable); -int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) +static int dsi_enable_te(struct omap_dss_device *dssdev, bool enable) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 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) dsi->te_enabled = enable; return 0; } -EXPORT_SYMBOL(omapdss_dsi_enable_te); #ifdef PRINT_VERBOSE_VM_TIMINGS static void print_dsi_vm(const char *str, @@ -5136,7 +5023,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi, dsi_vm_calc_pll_cb, ctx); } -int omapdss_dsi_set_config(struct omap_dss_device *dssdev, +static int dsi_set_config(struct omap_dss_device *dssdev, const struct omap_dss_dsi_config *config) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -5184,7 +5071,6 @@ err: return r; } -EXPORT_SYMBOL(omapdss_dsi_set_config); /* * 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) } } -int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) +static int dsi_request_vc(struct omap_dss_device *dssdev, int *channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 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) DSSERR("cannot get VC for display %s", dssdev->name); return -ENOSPC; } -EXPORT_SYMBOL(omap_dsi_request_vc); -int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) +static int dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 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) return 0; } -EXPORT_SYMBOL(omap_dsi_set_vc_id); -void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) +static void dsi_release_vc(struct omap_dss_device *dssdev, int channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 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) dsi->vc[channel].vc_id = 0; } } -EXPORT_SYMBOL(omap_dsi_release_vc); void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev) { @@ -5348,79 +5231,6 @@ static int dsi_get_clocks(struct platform_device *dsidev) return 0; } -static struct omap_dss_device *dsi_find_dssdev(struct platform_device *pdev) -{ - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); - const char *def_disp_name = omapdss_get_default_display_name(); - struct omap_dss_device *def_dssdev; - int i; - - def_dssdev = NULL; - - for (i = 0; i < pdata->num_devices; ++i) { - struct omap_dss_device *dssdev = pdata->devices[i]; - - if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) - continue; - - if (dssdev->phy.dsi.module != dsi->module_id) - continue; - - if (def_dssdev == NULL) - def_dssdev = dssdev; - - if (def_disp_name != NULL && - strcmp(dssdev->name, def_disp_name) == 0) { - def_dssdev = dssdev; - break; - } - } - - return def_dssdev; -} - -static int dsi_probe_pdata(struct platform_device *dsidev) -{ - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - struct omap_dss_device *plat_dssdev; - struct omap_dss_device *dssdev; - int r; - - plat_dssdev = dsi_find_dssdev(dsidev); - - if (!plat_dssdev) - return 0; - - r = dsi_regulator_init(dsidev); - if (r) - return r; - - dssdev = dss_alloc_and_init_device(&dsidev->dev); - if (!dssdev) - return -ENOMEM; - - dss_copy_device_pdata(dssdev, plat_dssdev); - - r = omapdss_output_set_device(&dsi->output, dssdev); - if (r) { - DSSERR("failed to connect output to new device: %s\n", - dssdev->name); - dss_put_device(dssdev); - return r; - } - - r = dss_add_device(dssdev); - if (r) { - DSSERR("device %s register failed: %d\n", dssdev->name, r); - omapdss_output_unset_device(&dsi->output); - dss_put_device(dssdev); - return r; - } - - return 0; -} - static int dsi_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { @@ -5454,9 +5264,9 @@ static int dsi_connect(struct omap_dss_device *dssdev, static void dsi_disconnect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - WARN_ON(dst != dssdev->device); + WARN_ON(dst != dssdev->dst); - if (dst != dssdev->device) + if (dst != dssdev->dst) return; omapdss_output_unset_device(dssdev); @@ -5472,24 +5282,24 @@ static const struct omapdss_dsi_ops dsi_ops = { .bus_lock = dsi_bus_lock, .bus_unlock = dsi_bus_unlock, - .enable = omapdss_dsi_display_enable, - .disable = omapdss_dsi_display_disable, + .enable = dsi_display_enable, + .disable = dsi_display_disable, - .enable_hs = omapdss_dsi_vc_enable_hs, + .enable_hs = dsi_vc_enable_hs, - .configure_pins = omapdss_dsi_configure_pins, - .set_config = omapdss_dsi_set_config, + .configure_pins = dsi_configure_pins, + .set_config = dsi_set_config, .enable_video_output = dsi_enable_video_output, .disable_video_output = dsi_disable_video_output, - .update = omap_dsi_update, + .update = dsi_update, - .enable_te = omapdss_dsi_enable_te, + .enable_te = dsi_enable_te, - .request_vc = omap_dsi_request_vc, - .set_vc_id = omap_dsi_set_vc_id, - .release_vc = omap_dsi_release_vc, + .request_vc = dsi_request_vc, + .set_vc_id = dsi_set_vc_id, + .release_vc = dsi_release_vc, .dcs_write = dsi_vc_dcs_write, .dcs_write_nosync = dsi_vc_dcs_write_nosync, @@ -5627,12 +5437,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev) dsi_init_output(dsidev); - if (dsidev->dev.platform_data) { - r = dsi_probe_pdata(dsidev); - if (r) - goto err_probe; - } - dsi_runtime_put(dsidev); if (dsi->module_id == 0) @@ -5648,9 +5452,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev) #endif return 0; -err_probe: - dsi_runtime_put(dsidev); - dsi_uninit_output(dsidev); err_runtime_get: pm_runtime_disable(&dsidev->dev); return r; @@ -5662,8 +5463,6 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) WARN_ON(dsi->scp_clk_refcount > 0); - dss_unregister_child_devices(&dsidev->dev); - dsi_uninit_output(dsidev); 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; /* core */ struct platform_device *dss_get_core_pdev(void); -struct bus_type *dss_get_bus(void); -struct regulator *dss_get_vdds_dsi(void); -struct regulator *dss_get_vdds_sdi(void); int dss_dsi_enable_pads(int dsi_id, unsigned lane_mask); void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask); int dss_set_min_bus_tput(struct device *dev, unsigned long tput); int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); -struct omap_dss_device *dss_alloc_and_init_device(struct device *parent); -int dss_add_device(struct omap_dss_device *dssdev); -void dss_unregister_device(struct omap_dss_device *dssdev); -void dss_unregister_child_devices(struct device *parent); -void dss_put_device(struct omap_dss_device *dssdev); -void dss_copy_device_pdata(struct omap_dss_device *dst, - const struct omap_dss_device *src); - /* display */ int dss_suspend_all_devices(void); int dss_resume_all_devices(void); @@ -436,44 +425,10 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi, /* VENC */ int venc_init_platform_driver(void) __init; void venc_uninit_platform_driver(void) __exit; -int omapdss_venc_display_enable(struct omap_dss_device *dssdev); -void omapdss_venc_display_disable(struct omap_dss_device *dssdev); -void omapdss_venc_set_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings); -int omapdss_venc_check_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings); -u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev); -int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss); -void omapdss_venc_set_type(struct omap_dss_device *dssdev, - enum omap_dss_venc_type type); -void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, - bool invert_polarity); -int venc_panel_init(void); -void venc_panel_exit(void); /* HDMI */ int hdmi_init_platform_driver(void) __init; void hdmi_uninit_platform_driver(void) __exit; -int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); -void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); -int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev); -void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev); -void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, - struct omap_video_timings *timings); -int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, - struct omap_video_timings *timings); -int omapdss_hdmi_read_edid(u8 *buf, int len); -bool omapdss_hdmi_detect(void); -int hdmi_panel_init(void); -void hdmi_panel_exit(void); -#ifdef CONFIG_OMAP4_DSS_HDMI_AUDIO -int hdmi_audio_enable(void); -void hdmi_audio_disable(void); -int hdmi_audio_start(void); -void hdmi_audio_stop(void); -bool hdmi_mode_has_audio(void); -int hdmi_audio_config(struct omap_dss_audio *audio); -#endif /* RFBI */ 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 { struct clk *sys_clk; struct regulator *vdda_hdmi_dac_reg; - int ct_cp_hpd_gpio; - int ls_oe_gpio; - int hpd_gpio; - bool core_enabled; struct omap_dss_device output; @@ -353,40 +349,6 @@ static int hdmi_init_regulator(void) return 0; } -static int hdmi_init_display(struct omap_dss_device *dssdev) -{ - int r; - - struct gpio gpios[] = { - { hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" }, - { hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" }, - { hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" }, - }; - - DSSDBG("init_display\n"); - - dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); - - r = hdmi_init_regulator(); - if (r) - return r; - - r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); - if (r) - return r; - - return 0; -} - -static void hdmi_uninit_display(struct omap_dss_device *dssdev) -{ - DSSDBG("uninit_display\n"); - - gpio_free(hdmi.ct_cp_hpd_gpio); - gpio_free(hdmi.ls_oe_gpio); - gpio_free(hdmi.hpd_gpio); -} - static const struct hdmi_config *hdmi_find_timing( const struct hdmi_config *timings_arr, int len) @@ -517,17 +479,9 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) { int r; - if (gpio_is_valid(hdmi.ct_cp_hpd_gpio)) - gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); - if (gpio_is_valid(hdmi.ls_oe_gpio)) - gpio_set_value(hdmi.ls_oe_gpio, 1); - - /* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */ - udelay(300); - r = regulator_enable(hdmi.vdda_hdmi_dac_reg); if (r) - goto err_vdac_enable; + return r; r = hdmi_runtime_get(); if (r) @@ -542,11 +496,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) err_runtime_get: regulator_disable(hdmi.vdda_hdmi_dac_reg); -err_vdac_enable: - if (gpio_is_valid(hdmi.ct_cp_hpd_gpio)) - gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); - if (gpio_is_valid(hdmi.ls_oe_gpio)) - gpio_set_value(hdmi.ls_oe_gpio, 0); + return r; } @@ -556,10 +506,6 @@ static void hdmi_power_off_core(struct omap_dss_device *dssdev) hdmi_runtime_put(); regulator_disable(hdmi.vdda_hdmi_dac_reg); - if (gpio_is_valid(hdmi.ct_cp_hpd_gpio)) - gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); - if (gpio_is_valid(hdmi.ls_oe_gpio)) - gpio_set_value(hdmi.ls_oe_gpio, 0); } 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) hdmi_power_off_core(dssdev); } -int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, +static int hdmi_display_check_timing(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { struct hdmi_cm cm; @@ -654,7 +600,7 @@ int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, } -void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, +static void hdmi_display_set_timing(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { struct hdmi_cm cm; @@ -666,15 +612,16 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, hdmi.ip_data.cfg.cm = cm; t = hdmi_get_timings(); - if (t != NULL) + if (t != NULL) { hdmi.ip_data.cfg = *t; - dispc_set_tv_pclk(t->timings.pixel_clock * 1000); + dispc_set_tv_pclk(t->timings.pixel_clock * 1000); + } mutex_unlock(&hdmi.lock); } -static void omapdss_hdmi_display_get_timings(struct omap_dss_device *dssdev, +static void hdmi_display_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { const struct hdmi_config *cfg; @@ -704,7 +651,7 @@ static void hdmi_dump_regs(struct seq_file *s) mutex_unlock(&hdmi.lock); } -int omapdss_hdmi_read_edid(u8 *buf, int len) +static int read_edid(u8 *buf, int len) { int r; @@ -721,24 +668,7 @@ int omapdss_hdmi_read_edid(u8 *buf, int len) return r; } -bool omapdss_hdmi_detect(void) -{ - int r; - - mutex_lock(&hdmi.lock); - - r = hdmi_runtime_get(); - BUG_ON(r); - - r = gpio_get_value(hdmi.hpd_gpio); - - hdmi_runtime_put(); - mutex_unlock(&hdmi.lock); - - return r == 1; -} - -int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) +static int hdmi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &hdmi.output; int r = 0; @@ -767,7 +697,7 @@ err0: return r; } -void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) +static void hdmi_display_disable(struct omap_dss_device *dssdev) { DSSDBG("Enter hdmi_display_disable\n"); @@ -778,7 +708,7 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) mutex_unlock(&hdmi.lock); } -int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev) +static int hdmi_core_enable(struct omap_dss_device *dssdev) { int r = 0; @@ -800,7 +730,7 @@ err0: return r; } -void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev) +static void hdmi_core_disable(struct omap_dss_device *dssdev) { DSSDBG("Enter omapdss_hdmi_core_disable\n"); @@ -927,35 +857,7 @@ int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) return 0; } -int hdmi_audio_enable(void) -{ - DSSDBG("audio_enable\n"); - - return hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); -} - -void hdmi_audio_disable(void) -{ - DSSDBG("audio_disable\n"); - - hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); -} - -int hdmi_audio_start(void) -{ - DSSDBG("audio_start\n"); - - return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); -} - -void hdmi_audio_stop(void) -{ - DSSDBG("audio_stop\n"); - - hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); -} - -bool hdmi_mode_has_audio(void) +static bool hdmi_mode_has_audio(void) { if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) return true; @@ -963,92 +865,8 @@ bool hdmi_mode_has_audio(void) return false; } -int hdmi_audio_config(struct omap_dss_audio *audio) -{ - return hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); -} - #endif -static struct omap_dss_device *hdmi_find_dssdev(struct platform_device *pdev) -{ - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = omapdss_get_default_display_name(); - struct omap_dss_device *def_dssdev; - int i; - - def_dssdev = NULL; - - for (i = 0; i < pdata->num_devices; ++i) { - struct omap_dss_device *dssdev = pdata->devices[i]; - - if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) - continue; - - if (def_dssdev == NULL) - def_dssdev = dssdev; - - if (def_disp_name != NULL && - strcmp(dssdev->name, def_disp_name) == 0) { - def_dssdev = dssdev; - break; - } - } - - return def_dssdev; -} - -static int hdmi_probe_pdata(struct platform_device *pdev) -{ - struct omap_dss_device *plat_dssdev; - struct omap_dss_device *dssdev; - struct omap_dss_hdmi_data *priv; - int r; - - plat_dssdev = hdmi_find_dssdev(pdev); - - if (!plat_dssdev) - return 0; - - dssdev = dss_alloc_and_init_device(&pdev->dev); - if (!dssdev) - return -ENOMEM; - - dss_copy_device_pdata(dssdev, plat_dssdev); - - priv = dssdev->data; - - hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio; - hdmi.ls_oe_gpio = priv->ls_oe_gpio; - hdmi.hpd_gpio = priv->hpd_gpio; - - r = hdmi_init_display(dssdev); - if (r) { - DSSERR("device %s init failed: %d\n", dssdev->name, r); - dss_put_device(dssdev); - return r; - } - - r = omapdss_output_set_device(&hdmi.output, dssdev); - if (r) { - DSSERR("failed to connect output to new device: %s\n", - dssdev->name); - dss_put_device(dssdev); - return r; - } - - r = dss_add_device(dssdev); - if (r) { - DSSERR("device %s register failed: %d\n", dssdev->name, r); - omapdss_output_unset_device(&hdmi.output); - hdmi_uninit_display(dssdev); - dss_put_device(dssdev); - return r; - } - - return 0; -} - static int hdmi_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { @@ -1083,9 +901,9 @@ static int hdmi_connect(struct omap_dss_device *dssdev, static void hdmi_disconnect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - WARN_ON(dst != dssdev->device); + WARN_ON(dst != dssdev->dst); - if (dst != dssdev->device) + if (dst != dssdev->dst) return; omapdss_output_unset_device(dssdev); @@ -1103,21 +921,21 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, need_enable = hdmi.core_enabled == false; if (need_enable) { - r = omapdss_hdmi_core_enable(dssdev); + r = hdmi_core_enable(dssdev); if (r) return r; } - r = omapdss_hdmi_read_edid(edid, len); + r = read_edid(edid, len); if (need_enable) - omapdss_hdmi_core_disable(dssdev); + hdmi_core_disable(dssdev); return r; } #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) +static int hdmi_audio_enable(struct omap_dss_device *dssdev) { int r; @@ -1128,7 +946,8 @@ static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) goto err; } - r = hdmi_audio_enable(); + + r = hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); if (r) goto err; @@ -1140,22 +959,22 @@ err: return r; } -static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev) +static void hdmi_audio_disable(struct omap_dss_device *dssdev) { - hdmi_audio_disable(); + hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); } -static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev) +static int hdmi_audio_start(struct omap_dss_device *dssdev) { - return hdmi_audio_start(); + return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); } -static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev) +static void hdmi_audio_stop(struct omap_dss_device *dssdev) { - hdmi_audio_stop(); + hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); } -static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) +static bool hdmi_audio_supported(struct omap_dss_device *dssdev) { bool r; @@ -1167,7 +986,7 @@ static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) return r; } -static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, +static int hdmi_audio_config(struct omap_dss_device *dssdev, struct omap_dss_audio *audio) { int r; @@ -1179,7 +998,7 @@ static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, goto err; } - r = hdmi_audio_config(audio); + r = hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); if (r) goto err; @@ -1191,30 +1010,30 @@ err: return r; } #else -static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev) +static int hdmi_audio_enable(struct omap_dss_device *dssdev) { return -EPERM; } -static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev) +static void hdmi_audio_disable(struct omap_dss_device *dssdev) { } -static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev) +static int hdmi_audio_start(struct omap_dss_device *dssdev) { return -EPERM; } -static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev) +static void hdmi_audio_stop(struct omap_dss_device *dssdev) { } -static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev) +static bool hdmi_audio_supported(struct omap_dss_device *dssdev) { return false; } -static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev, +static int hdmi_audio_config(struct omap_dss_device *dssdev, struct omap_dss_audio *audio) { return -EPERM; @@ -1225,21 +1044,21 @@ static const struct omapdss_hdmi_ops hdmi_ops = { .connect = hdmi_connect, .disconnect = hdmi_disconnect, - .enable = omapdss_hdmi_display_enable, - .disable = omapdss_hdmi_display_disable, + .enable = hdmi_display_enable, + .disable = hdmi_display_disable, - .check_timings = omapdss_hdmi_display_check_timing, - .set_timings = omapdss_hdmi_display_set_timing, - .get_timings = omapdss_hdmi_display_get_timings, + .check_timings = hdmi_display_check_timing, + .set_timings = hdmi_display_set_timing, + .get_timings = hdmi_display_get_timings, .read_edid = hdmi_read_edid, - .audio_enable = omapdss_hdmi_audio_enable, - .audio_disable = omapdss_hdmi_audio_disable, - .audio_start = omapdss_hdmi_audio_start, - .audio_stop = omapdss_hdmi_audio_stop, - .audio_supported = omapdss_hdmi_audio_supported, - .audio_config = omapdss_hdmi_audio_config, + .audio_enable = hdmi_audio_enable, + .audio_disable = hdmi_audio_disable, + .audio_start = hdmi_audio_start, + .audio_stop = hdmi_audio_stop, + .audio_supported = hdmi_audio_supported, + .audio_config = hdmi_audio_config, }; static void hdmi_init_output(struct platform_device *pdev) @@ -1301,50 +1120,15 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) hdmi.ip_data.pll_offset = HDMI_PLLCTRL; hdmi.ip_data.phy_offset = HDMI_PHY; - hdmi.ct_cp_hpd_gpio = -1; - hdmi.ls_oe_gpio = -1; - hdmi.hpd_gpio = -1; - hdmi_init_output(pdev); - r = hdmi_panel_init(); - if (r) { - DSSERR("can't init panel\n"); - return r; - } - dss_debugfs_create_file("hdmi", hdmi_dump_regs); - if (pdev->dev.platform_data) { - r = hdmi_probe_pdata(pdev); - if (r) - goto err_probe; - } - - return 0; - -err_probe: - hdmi_panel_exit(); - hdmi_uninit_output(pdev); - pm_runtime_disable(&pdev->dev); - return r; -} - -static int __exit hdmi_remove_child(struct device *dev, void *data) -{ - struct omap_dss_device *dssdev = to_dss_device(dev); - hdmi_uninit_display(dssdev); return 0; } static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) { - device_for_each_child(&pdev->dev, NULL, hdmi_remove_child); - - dss_unregister_child_devices(&pdev->dev); - - hdmi_panel_exit(); - hdmi_uninit_output(pdev); 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 @@ -/* - * hdmi_panel.c - * - * HDMI library support functions for TI OMAP4 processors. - * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ - * Authors: Mythri P k <mythripk@ti.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/mutex.h> -#include <linux/module.h> -#include <video/omapdss.h> -#include <linux/slab.h> - -#include "dss.h" - -static struct { - /* This protects the panel ops, mainly when accessing the HDMI IP. */ - struct mutex lock; -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) - /* This protects the audio ops, specifically. */ - spinlock_t audio_lock; -#endif -} hdmi; - - -static int hdmi_panel_probe(struct omap_dss_device *dssdev) -{ - /* Initialize default timings to VGA in DVI mode */ - const struct omap_video_timings default_timings = { - .x_res = 640, - .y_res = 480, - .pixel_clock = 25175, - .hsw = 96, - .hfp = 16, - .hbp = 48, - .vsw = 2, - .vfp = 11, - .vbp = 31, - - .vsync_level = OMAPDSS_SIG_ACTIVE_LOW, - .hsync_level = OMAPDSS_SIG_ACTIVE_LOW, - - .interlace = false, - }; - - DSSDBG("ENTER hdmi_panel_probe\n"); - - dssdev->panel.timings = default_timings; - - DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", - dssdev->panel.timings.x_res, - dssdev->panel.timings.y_res); - - omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings); - - return 0; -} - -static void hdmi_panel_remove(struct omap_dss_device *dssdev) -{ - -} - -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) -{ - unsigned long flags; - int r; - - mutex_lock(&hdmi.lock); - spin_lock_irqsave(&hdmi.audio_lock, flags); - - /* enable audio only if the display is active and supports audio */ - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || - !hdmi_mode_has_audio()) { - DSSERR("audio not supported or display is off\n"); - r = -EPERM; - goto err; - } - - r = hdmi_audio_enable(); - - if (!r) - dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; - -err: - spin_unlock_irqrestore(&hdmi.audio_lock, flags); - mutex_unlock(&hdmi.lock); - return r; -} - -static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) -{ - unsigned long flags; - - spin_lock_irqsave(&hdmi.audio_lock, flags); - - hdmi_audio_disable(); - - dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED; - - spin_unlock_irqrestore(&hdmi.audio_lock, flags); -} - -static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) -{ - unsigned long flags; - int r; - - spin_lock_irqsave(&hdmi.audio_lock, flags); - /* - * No need to check the panel state. It was checked when trasitioning - * to AUDIO_ENABLED. - */ - if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED) { - DSSERR("audio start from invalid state\n"); - r = -EPERM; - goto err; - } - - r = hdmi_audio_start(); - - if (!r) - dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING; - -err: - spin_unlock_irqrestore(&hdmi.audio_lock, flags); - return r; -} - -static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) -{ - unsigned long flags; - - spin_lock_irqsave(&hdmi.audio_lock, flags); - - hdmi_audio_stop(); - dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED; - - spin_unlock_irqrestore(&hdmi.audio_lock, flags); -} - -static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) -{ - bool r = false; - - mutex_lock(&hdmi.lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - goto err; - - if (!hdmi_mode_has_audio()) - goto err; - - r = true; -err: - mutex_unlock(&hdmi.lock); - return r; -} - -static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, - struct omap_dss_audio *audio) -{ - unsigned long flags; - int r; - - mutex_lock(&hdmi.lock); - spin_lock_irqsave(&hdmi.audio_lock, flags); - - /* config audio only if the display is active and supports audio */ - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || - !hdmi_mode_has_audio()) { - DSSERR("audio not supported or display is off\n"); - r = -EPERM; - goto err; - } - - r = hdmi_audio_config(audio); - - if (!r) - dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED; - -err: - spin_unlock_irqrestore(&hdmi.audio_lock, flags); - mutex_unlock(&hdmi.lock); - return r; -} - -#else -static int hdmi_panel_audio_enable(struct omap_dss_device *dssdev) -{ - return -EPERM; -} - -static void hdmi_panel_audio_disable(struct omap_dss_device *dssdev) -{ -} - -static int hdmi_panel_audio_start(struct omap_dss_device *dssdev) -{ - return -EPERM; -} - -static void hdmi_panel_audio_stop(struct omap_dss_device *dssdev) -{ -} - -static bool hdmi_panel_audio_supported(struct omap_dss_device *dssdev) -{ - return false; -} - -static int hdmi_panel_audio_config(struct omap_dss_device *dssdev, - struct omap_dss_audio *audio) -{ - return -EPERM; -} -#endif - -static int hdmi_panel_enable(struct omap_dss_device *dssdev) -{ - int r = 0; - DSSDBG("ENTER hdmi_panel_enable\n"); - - mutex_lock(&hdmi.lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { - r = -EINVAL; - goto err; - } - - omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings); - - r = omapdss_hdmi_display_enable(dssdev); - if (r) { - DSSERR("failed to power on\n"); - goto err; - } - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - -err: - mutex_unlock(&hdmi.lock); - - return r; -} - -static void hdmi_panel_disable(struct omap_dss_device *dssdev) -{ - mutex_lock(&hdmi.lock); - - if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { - /* - * TODO: notify audio users that the display was disabled. For - * now, disable audio locally to not break our audio state - * machine. - */ - hdmi_panel_audio_disable(dssdev); - omapdss_hdmi_display_disable(dssdev); - } - - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - - mutex_unlock(&hdmi.lock); -} - -static void hdmi_get_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - mutex_lock(&hdmi.lock); - - *timings = dssdev->panel.timings; - - mutex_unlock(&hdmi.lock); -} - -static void hdmi_set_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - DSSDBG("hdmi_set_timings\n"); - - mutex_lock(&hdmi.lock); - - /* - * TODO: notify audio users that there was a timings change. For - * now, disable audio locally to not break our audio state machine. - */ - hdmi_panel_audio_disable(dssdev); - - omapdss_hdmi_display_set_timing(dssdev, timings); - dssdev->panel.timings = *timings; - - mutex_unlock(&hdmi.lock); -} - -static int hdmi_check_timings(struct omap_dss_device *dssdev, - struct omap_video_timings *timings) -{ - int r = 0; - - DSSDBG("hdmi_check_timings\n"); - - mutex_lock(&hdmi.lock); - - r = omapdss_hdmi_display_check_timing(dssdev, timings); - - mutex_unlock(&hdmi.lock); - return r; -} - -static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) -{ - int r; - bool need_enable; - - mutex_lock(&hdmi.lock); - - need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; - - if (need_enable) { - r = omapdss_hdmi_core_enable(dssdev); - if (r) - goto err; - } - - r = omapdss_hdmi_read_edid(buf, len); - - if (need_enable) - omapdss_hdmi_core_disable(dssdev); -err: - mutex_unlock(&hdmi.lock); - - return r; -} - -static bool hdmi_detect(struct omap_dss_device *dssdev) -{ - int r; - bool need_enable; - - mutex_lock(&hdmi.lock); - - need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; - - if (need_enable) { - r = omapdss_hdmi_core_enable(dssdev); - if (r) - goto err; - } - - r = omapdss_hdmi_detect(); - - if (need_enable) - omapdss_hdmi_core_disable(dssdev); -err: - mutex_unlock(&hdmi.lock); - - return r; -} - -static struct omap_dss_driver hdmi_driver = { - .probe = hdmi_panel_probe, - .remove = hdmi_panel_remove, - .enable = hdmi_panel_enable, - .disable = hdmi_panel_disable, - .get_timings = hdmi_get_timings, - .set_timings = hdmi_set_timings, - .check_timings = hdmi_check_timings, - .read_edid = hdmi_read_edid, - .detect = hdmi_detect, - .audio_enable = hdmi_panel_audio_enable, - .audio_disable = hdmi_panel_audio_disable, - .audio_start = hdmi_panel_audio_start, - .audio_stop = hdmi_panel_audio_stop, - .audio_supported = hdmi_panel_audio_supported, - .audio_config = hdmi_panel_audio_config, - .driver = { - .name = "hdmi_panel", - .owner = THIS_MODULE, - }, -}; - -int hdmi_panel_init(void) -{ - mutex_init(&hdmi.lock); - -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) - spin_lock_init(&hdmi.audio_lock); -#endif - - return omap_dss_register_driver(&hdmi_driver); -} - -void hdmi_panel_exit(void) -{ - omap_dss_unregister_driver(&hdmi_driver); - -} 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( { struct omap_overlay_manager_info info; - mgr->get_manager_info(mgr, &info); + if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) + return -ENODEV; - WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); + mgr->get_manager_info(mgr, &info); return snprintf(buf, PAGE_SIZE, "%d\n", info.partial_alpha_enabled); @@ -301,7 +302,8 @@ static ssize_t manager_alpha_blending_enabled_store( bool enable; int r; - WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)); + if(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) + return -ENODEV; r = strtobool(buf, &enable); 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, mutex_lock(&output_lock); - if (out->device) { + if (out->dst) { DSSERR("output already has device %s connected to it\n", - out->device->name); + out->dst->name); r = -EINVAL; goto err; } @@ -47,8 +47,8 @@ int omapdss_output_set_device(struct omap_dss_device *out, goto err; } - out->device = dssdev; - dssdev->output = out; + out->dst = dssdev; + dssdev->src = out; mutex_unlock(&output_lock); @@ -66,21 +66,21 @@ int omapdss_output_unset_device(struct omap_dss_device *out) mutex_lock(&output_lock); - if (!out->device) { + if (!out->dst) { DSSERR("output doesn't have a device connected to it\n"); r = -EINVAL; goto err; } - if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) { + if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) { DSSERR("device %s is not disabled, cannot unset device\n", - out->device->name); + out->dst->name); r = -EINVAL; goto err; } - out->device->output = NULL; - out->device = NULL; + out->dst->src = NULL; + out->dst = NULL; mutex_unlock(&output_lock); @@ -146,8 +146,8 @@ EXPORT_SYMBOL(omap_dss_find_output_by_node); struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev) { - while (dssdev->output) - dssdev = dssdev->output; + while (dssdev->src) + dssdev = dssdev->src; if (dssdev->id != 0) 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) WARN_ON(r < 0 && r != -ENOSYS); } -void rfbi_bus_lock(void) +static void rfbi_bus_lock(void) { down(&rfbi.bus_lock); } -EXPORT_SYMBOL(rfbi_bus_lock); -void rfbi_bus_unlock(void) +static void rfbi_bus_unlock(void) { up(&rfbi.bus_lock); } -EXPORT_SYMBOL(rfbi_bus_unlock); -void omap_rfbi_write_command(const void *buf, u32 len) +static void rfbi_write_command(const void *buf, u32 len) { switch (rfbi.parallelmode) { case OMAP_DSS_RFBI_PARALLELMODE_8: @@ -189,9 +187,8 @@ void omap_rfbi_write_command(const void *buf, u32 len) BUG(); } } -EXPORT_SYMBOL(omap_rfbi_write_command); -void omap_rfbi_read_data(void *buf, u32 len) +static void rfbi_read_data(void *buf, u32 len) { switch (rfbi.parallelmode) { case OMAP_DSS_RFBI_PARALLELMODE_8: @@ -221,9 +218,8 @@ void omap_rfbi_read_data(void *buf, u32 len) BUG(); } } -EXPORT_SYMBOL(omap_rfbi_read_data); -void omap_rfbi_write_data(const void *buf, u32 len) +static void rfbi_write_data(const void *buf, u32 len) { switch (rfbi.parallelmode) { case OMAP_DSS_RFBI_PARALLELMODE_8: @@ -250,9 +246,8 @@ void omap_rfbi_write_data(const void *buf, u32 len) } } -EXPORT_SYMBOL(omap_rfbi_write_data); -void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, +static void rfbi_write_pixels(const void __iomem *buf, int scr_width, u16 x, u16 y, u16 w, u16 h) { @@ -305,7 +300,6 @@ void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width, BUG(); } } -EXPORT_SYMBOL(omap_rfbi_write_pixels); static int rfbi_transfer_area(struct omap_dss_device *dssdev, void (*callback)(void *data), void *data) @@ -574,7 +568,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t) } /* xxx FIX module selection missing */ -int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode, +static int rfbi_setup_te(enum omap_rfbi_te_mode mode, unsigned hs_pulse_time, unsigned vs_pulse_time, int hs_pol_inv, int vs_pol_inv, int extif_div) { @@ -613,10 +607,9 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode, return 0; } -EXPORT_SYMBOL(omap_rfbi_setup_te); /* xxx FIX module selection missing */ -int omap_rfbi_enable_te(bool enable, unsigned line) +static int rfbi_enable_te(bool enable, unsigned line) { u32 l; @@ -636,9 +629,8 @@ int omap_rfbi_enable_te(bool enable, unsigned line) return 0; } -EXPORT_SYMBOL(omap_rfbi_enable_te); -static int rfbi_configure(int rfbi_module, int bpp, int lines) +static int rfbi_configure_bus(int rfbi_module, int bpp, int lines) { u32 l; int cycle1 = 0, cycle2 = 0, cycle3 = 0; @@ -770,45 +762,39 @@ static int rfbi_configure(int rfbi_module, int bpp, int lines) return 0; } -int omap_rfbi_configure(struct omap_dss_device *dssdev) +static int rfbi_configure(struct omap_dss_device *dssdev) { - return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size, + return rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size, rfbi.data_lines); } -EXPORT_SYMBOL(omap_rfbi_configure); -int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *), +static int rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *), void *data) { return rfbi_transfer_area(dssdev, callback, data); } -EXPORT_SYMBOL(omap_rfbi_update); -void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) +static void rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) { rfbi.timings.x_res = w; rfbi.timings.y_res = h; } -EXPORT_SYMBOL(omapdss_rfbi_set_size); -void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size) +static void rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size) { rfbi.pixel_size = pixel_size; } -EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size); -void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) +static void rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) { rfbi.data_lines = data_lines; } -EXPORT_SYMBOL(omapdss_rfbi_set_data_lines); -void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev, +static void rfbi_set_interface_timings(struct omap_dss_device *dssdev, struct rfbi_timings *timings) { rfbi.intf_timings = *timings; } -EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings); static void rfbi_dump_regs(struct seq_file *s) { @@ -888,7 +874,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) dss_mgr_set_timings(mgr, &rfbi.timings); } -int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) +static int rfbi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &rfbi.output; int r; @@ -911,7 +897,7 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) rfbi_config_lcd_manager(dssdev); - rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size, + rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size, rfbi.data_lines); rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings); @@ -921,9 +907,8 @@ err1: rfbi_runtime_put(); return r; } -EXPORT_SYMBOL(omapdss_rfbi_display_enable); -void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) +static void rfbi_display_disable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &rfbi.output; @@ -932,7 +917,6 @@ void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev) rfbi_runtime_put(); } -EXPORT_SYMBOL(omapdss_rfbi_display_disable); static int rfbi_init_display(struct omap_dss_device *dssdev) { @@ -940,77 +924,6 @@ static int rfbi_init_display(struct omap_dss_device *dssdev) return 0; } -static struct omap_dss_device *rfbi_find_dssdev(struct platform_device *pdev) -{ - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = omapdss_get_default_display_name(); - struct omap_dss_device *def_dssdev; - int i; - - def_dssdev = NULL; - - for (i = 0; i < pdata->num_devices; ++i) { - struct omap_dss_device *dssdev = pdata->devices[i]; - - if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) - continue; - - if (def_dssdev == NULL) - def_dssdev = dssdev; - - if (def_disp_name != NULL && - strcmp(dssdev->name, def_disp_name) == 0) { - def_dssdev = dssdev; - break; - } - } - - return def_dssdev; -} - -static int rfbi_probe_pdata(struct platform_device *rfbidev) -{ - struct omap_dss_device *plat_dssdev; - struct omap_dss_device *dssdev; - int r; - - plat_dssdev = rfbi_find_dssdev(rfbidev); - - if (!plat_dssdev) - return 0; - - dssdev = dss_alloc_and_init_device(&rfbidev->dev); - if (!dssdev) - return -ENOMEM; - - dss_copy_device_pdata(dssdev, plat_dssdev); - - r = rfbi_init_display(dssdev); - if (r) { - DSSERR("device %s init failed: %d\n", dssdev->name, r); - dss_put_device(dssdev); - return r; - } - - r = omapdss_output_set_device(&rfbi.output, dssdev); - if (r) { - DSSERR("failed to connect output to new device: %s\n", - dssdev->name); - dss_put_device(dssdev); - return r; - } - - r = dss_add_device(dssdev); - if (r) { - DSSERR("device %s register failed: %d\n", dssdev->name, r); - omapdss_output_unset_device(&rfbi.output); - dss_put_device(dssdev); - return r; - } - - return 0; -} - static void rfbi_init_output(struct platform_device *pdev) { struct omap_dss_device *out = &rfbi.output; @@ -1085,16 +998,8 @@ static int omap_rfbihw_probe(struct platform_device *pdev) rfbi_init_output(pdev); - if (pdev->dev.platform_data) { - r = rfbi_probe_pdata(pdev); - if (r) - goto err_probe; - } - return 0; -err_probe: - rfbi_uninit_output(pdev); err_runtime_get: pm_runtime_disable(&pdev->dev); return r; @@ -1102,8 +1007,6 @@ err_runtime_get: static int __exit omap_rfbihw_remove(struct platform_device *pdev) { - dss_unregister_child_devices(&pdev->dev); - rfbi_uninit_output(pdev); 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) dss_mgr_set_lcd_config(mgr, &sdi.mgr_config); } -int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) +static int sdi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &sdi.output; struct omap_video_timings *t = &sdi.timings; @@ -211,9 +211,8 @@ err_get_dispc: err_reg_enable: return r; } -EXPORT_SYMBOL(omapdss_sdi_display_enable); -void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) +static void sdi_display_disable(struct omap_dss_device *dssdev) { struct omap_overlay_manager *mgr = sdi.output.manager; @@ -225,14 +224,12 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) regulator_disable(sdi.vdds_sdi_reg); } -EXPORT_SYMBOL(omapdss_sdi_display_disable); -void omapdss_sdi_set_timings(struct omap_dss_device *dssdev, +static void sdi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { sdi.timings = *timings; } -EXPORT_SYMBOL(omapdss_sdi_set_timings); static void sdi_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) @@ -254,11 +251,10 @@ static int sdi_check_timings(struct omap_dss_device *dssdev, return 0; } -void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs) +static void sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs) { sdi.datapairs = datapairs; } -EXPORT_SYMBOL(omapdss_sdi_set_datapairs); static int sdi_init_regulator(void) { @@ -267,14 +263,10 @@ static int sdi_init_regulator(void) if (sdi.vdds_sdi_reg) return 0; - vdds_sdi = dss_get_vdds_sdi(); - + vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi"); if (IS_ERR(vdds_sdi)) { - vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi"); - if (IS_ERR(vdds_sdi)) { - DSSERR("can't get VDDS_SDI regulator\n"); - return PTR_ERR(vdds_sdi); - } + DSSERR("can't get VDDS_SDI regulator\n"); + return PTR_ERR(vdds_sdi); } sdi.vdds_sdi_reg = vdds_sdi; @@ -282,77 +274,6 @@ static int sdi_init_regulator(void) return 0; } -static struct omap_dss_device *sdi_find_dssdev(struct platform_device *pdev) -{ - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = omapdss_get_default_display_name(); - struct omap_dss_device *def_dssdev; - int i; - - def_dssdev = NULL; - - for (i = 0; i < pdata->num_devices; ++i) { - struct omap_dss_device *dssdev = pdata->devices[i]; - - if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) - continue; - - if (def_dssdev == NULL) - def_dssdev = dssdev; - - if (def_disp_name != NULL && - strcmp(dssdev->name, def_disp_name) == 0) { - def_dssdev = dssdev; - break; - } - } - - return def_dssdev; -} - -static int sdi_probe_pdata(struct platform_device *sdidev) -{ - struct omap_dss_device *plat_dssdev; - struct omap_dss_device *dssdev; - int r; - - plat_dssdev = sdi_find_dssdev(sdidev); - - if (!plat_dssdev) - return 0; - - dssdev = dss_alloc_and_init_device(&sdidev->dev); - if (!dssdev) - return -ENOMEM; - - dss_copy_device_pdata(dssdev, plat_dssdev); - - r = sdi_init_regulator(); - if (r) { - DSSERR("device %s init failed: %d\n", dssdev->name, r); - dss_put_device(dssdev); - return r; - } - - r = omapdss_output_set_device(&sdi.output, dssdev); - if (r) { - DSSERR("failed to connect output to new device: %s\n", - dssdev->name); - dss_put_device(dssdev); - return r; - } - - r = dss_add_device(dssdev); - if (r) { - DSSERR("device %s register failed: %d\n", dssdev->name, r); - omapdss_output_unset_device(&sdi.output); - dss_put_device(dssdev); - return r; - } - - return 0; -} - static int sdi_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { @@ -385,9 +306,9 @@ static int sdi_connect(struct omap_dss_device *dssdev, static void sdi_disconnect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - WARN_ON(dst != dssdev->device); + WARN_ON(dst != dssdev->dst); - if (dst != dssdev->device) + if (dst != dssdev->dst) return; omapdss_output_unset_device(dssdev); @@ -400,14 +321,14 @@ static const struct omapdss_sdi_ops sdi_ops = { .connect = sdi_connect, .disconnect = sdi_disconnect, - .enable = omapdss_sdi_display_enable, - .disable = omapdss_sdi_display_disable, + .enable = sdi_display_enable, + .disable = sdi_display_disable, .check_timings = sdi_check_timings, - .set_timings = omapdss_sdi_set_timings, + .set_timings = sdi_set_timings, .get_timings = sdi_get_timings, - .set_datapairs = omapdss_sdi_set_datapairs, + .set_datapairs = sdi_set_datapairs, }; static void sdi_init_output(struct platform_device *pdev) @@ -434,29 +355,15 @@ static void __exit sdi_uninit_output(struct platform_device *pdev) static int omap_sdi_probe(struct platform_device *pdev) { - int r; - sdi.pdev = pdev; sdi_init_output(pdev); - if (pdev->dev.platform_data) { - r = sdi_probe_pdata(pdev); - if (r) - goto err_probe; - } - return 0; - -err_probe: - sdi_uninit_output(pdev); - return r; } static int __exit omap_sdi_remove(struct platform_device *pdev) { - dss_unregister_child_devices(&pdev->dev); - sdi_uninit_output(pdev); 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) struct omap_video_timings video_timing; struct hdmi_video_format video_format; /* HDMI core */ - struct hdmi_core_infoframe_avi avi_cfg = ip_data->avi_cfg; + struct hdmi_core_infoframe_avi *avi_cfg = &ip_data->avi_cfg; struct hdmi_core_video_config v_core_cfg; struct hdmi_core_packet_enable_repeat repeat_cfg; struct hdmi_config *cfg = &ip_data->cfg; hdmi_wp_init(&video_timing, &video_format); - hdmi_core_init(&v_core_cfg, - &avi_cfg, - &repeat_cfg); + hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); hdmi_wp_video_init_format(&video_format, &video_timing, cfg); @@ -822,24 +820,24 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) * configure packet * info frame video see doc CEA861-D page 65 */ - avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; - avi_cfg.db1_active_info = - HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; - avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; - avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; - avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; - avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; - avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; - avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; - avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; - avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; - avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; - avi_cfg.db4_videocode = cfg->cm.code; - avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; - avi_cfg.db6_7_line_eoftop = 0; - avi_cfg.db8_9_line_sofbottom = 0; - avi_cfg.db10_11_pixel_eofleft = 0; - avi_cfg.db12_13_pixel_sofright = 0; + avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; + avi_cfg->db1_active_info = + HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; + avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; + avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; + avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; + avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; + avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; + avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; + avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; + avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; + avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; + avi_cfg->db4_videocode = cfg->cm.code; + avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; + avi_cfg->db6_7_line_eoftop = 0; + avi_cfg->db8_9_line_sofbottom = 0; + avi_cfg->db10_11_pixel_eofleft = 0; + avi_cfg->db12_13_pixel_sofright = 0; hdmi_core_aux_infoframe_avi_config(ip_data); 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) venc_runtime_put(); } -int omapdss_venc_display_enable(struct omap_dss_device *dssdev) +static int venc_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &venc.output; int r; @@ -521,7 +521,7 @@ err0: return r; } -void omapdss_venc_display_disable(struct omap_dss_device *dssdev) +static void venc_display_disable(struct omap_dss_device *dssdev) { DSSDBG("venc_display_disable\n"); @@ -532,7 +532,7 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev) mutex_unlock(&venc.venc_lock); } -void omapdss_venc_set_timings(struct omap_dss_device *dssdev, +static void venc_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { DSSDBG("venc_set_timings\n"); @@ -550,7 +550,7 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev, mutex_unlock(&venc.venc_lock); } -int omapdss_venc_check_timings(struct omap_dss_device *dssdev, +static int venc_check_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { DSSDBG("venc_check_timings\n"); @@ -574,13 +574,13 @@ static void venc_get_timings(struct omap_dss_device *dssdev, mutex_unlock(&venc.venc_lock); } -u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev) +static u32 venc_get_wss(struct omap_dss_device *dssdev) { /* Invert due to VENC_L21_WC_CTL:INV=1 */ return (venc.wss_data >> 8) ^ 0xfffff; } -int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss) +static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss) { const struct venc_config *config; int r; @@ -609,7 +609,7 @@ err: return r; } -void omapdss_venc_set_type(struct omap_dss_device *dssdev, +static void venc_set_type(struct omap_dss_device *dssdev, enum omap_dss_venc_type type) { mutex_lock(&venc.venc_lock); @@ -619,7 +619,7 @@ void omapdss_venc_set_type(struct omap_dss_device *dssdev, mutex_unlock(&venc.venc_lock); } -void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, +static void venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, bool invert_polarity) { mutex_lock(&venc.venc_lock); @@ -721,74 +721,6 @@ static int venc_get_clocks(struct platform_device *pdev) return 0; } -static struct omap_dss_device *venc_find_dssdev(struct platform_device *pdev) -{ - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = omapdss_get_default_display_name(); - struct omap_dss_device *def_dssdev; - int i; - - def_dssdev = NULL; - - for (i = 0; i < pdata->num_devices; ++i) { - struct omap_dss_device *dssdev = pdata->devices[i]; - - if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) - continue; - - if (def_dssdev == NULL) - def_dssdev = dssdev; - - if (def_disp_name != NULL && - strcmp(dssdev->name, def_disp_name) == 0) { - def_dssdev = dssdev; - break; - } - } - - return def_dssdev; -} - -static int venc_probe_pdata(struct platform_device *vencdev) -{ - struct omap_dss_device *plat_dssdev; - struct omap_dss_device *dssdev; - int r; - - plat_dssdev = venc_find_dssdev(vencdev); - - if (!plat_dssdev) - return 0; - - r = venc_init_regulator(); - if (r) - return r; - - dssdev = dss_alloc_and_init_device(&vencdev->dev); - if (!dssdev) - return -ENOMEM; - - dss_copy_device_pdata(dssdev, plat_dssdev); - - r = omapdss_output_set_device(&venc.output, dssdev); - if (r) { - DSSERR("failed to connect output to new device: %s\n", - dssdev->name); - dss_put_device(dssdev); - return r; - } - - r = dss_add_device(dssdev); - if (r) { - DSSERR("device %s register failed: %d\n", dssdev->name, r); - omapdss_output_unset_device(&venc.output); - dss_put_device(dssdev); - return r; - } - - return 0; -} - static int venc_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { @@ -821,9 +753,9 @@ static int venc_connect(struct omap_dss_device *dssdev, static void venc_disconnect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - WARN_ON(dst != dssdev->device); + WARN_ON(dst != dssdev->dst); - if (dst != dssdev->device) + if (dst != dssdev->dst) return; omapdss_output_unset_device(dssdev); @@ -836,18 +768,18 @@ static const struct omapdss_atv_ops venc_ops = { .connect = venc_connect, .disconnect = venc_disconnect, - .enable = omapdss_venc_display_enable, - .disable = omapdss_venc_display_disable, + .enable = venc_display_enable, + .disable = venc_display_disable, - .check_timings = omapdss_venc_check_timings, - .set_timings = omapdss_venc_set_timings, + .check_timings = venc_check_timings, + .set_timings = venc_set_timings, .get_timings = venc_get_timings, - .set_type = omapdss_venc_set_type, - .invert_vid_out_polarity = omapdss_venc_invert_vid_out_polarity, + .set_type = venc_set_type, + .invert_vid_out_polarity = venc_invert_vid_out_polarity, - .set_wss = omapdss_venc_set_wss, - .get_wss = omapdss_venc_get_wss, + .set_wss = venc_set_wss, + .get_wss = venc_get_wss, }; static void venc_init_output(struct platform_device *pdev) @@ -913,26 +845,12 @@ static int omap_venchw_probe(struct platform_device *pdev) venc_runtime_put(); - r = venc_panel_init(); - if (r) - goto err_panel_init; - dss_debugfs_create_file("venc", venc_dump_regs); venc_init_output(pdev); - if (pdev->dev.platform_data) { - r = venc_probe_pdata(pdev); - if (r) - goto err_probe; - } - return 0; -err_probe: - venc_panel_exit(); - venc_uninit_output(pdev); -err_panel_init: err_runtime_get: pm_runtime_disable(&pdev->dev); return r; @@ -940,10 +858,6 @@ err_runtime_get: static int __exit omap_venchw_remove(struct platform_device *pdev) { - dss_unregister_child_devices(&pdev->dev); - - venc_panel_exit(); - venc_uninit_output(pdev); 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"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); -static ssize_t video_output_show_state(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t state_show(struct device *dev, struct device_attribute *attr, + char *buf) { ssize_t ret_size = 0; struct output_device *od = to_output_device(dev); @@ -42,9 +42,8 @@ static ssize_t video_output_show_state(struct device *dev, return ret_size; } -static ssize_t video_output_store_state(struct device *dev, - struct device_attribute *attr, - const char *buf,size_t count) +static ssize_t state_store(struct device *dev, struct device_attribute *attr, + const char *buf,size_t count) { char *endp; struct output_device *od = to_output_device(dev); @@ -62,6 +61,7 @@ static ssize_t video_output_store_state(struct device *dev, } return count; } +static DEVICE_ATTR_RW(state); static void video_output_release(struct device *dev) { @@ -69,16 +69,16 @@ static void video_output_release(struct device *dev) kfree(od); } -static struct device_attribute video_output_attributes[] = { - __ATTR(state, 0644, video_output_show_state, video_output_store_state), - __ATTR_NULL, +static struct attribute *video_output_attrs[] = { + &dev_attr_state.attr, + NULL, }; - +ATTRIBUTE_GROUPS(video_output); static struct class video_output_class = { .name = "video_output", .dev_release = video_output_release, - .dev_attrs = video_output_attributes, + .dev_groups = video_output_groups, }; struct output_device *video_output_register(const char *name, 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 @@ #include <linux/fb.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/platform_data/simplefb.h> #include <linux/platform_device.h> static struct fb_fix_screeninfo simplefb_fix = { @@ -73,18 +74,7 @@ static struct fb_ops simplefb_ops = { .fb_imageblit = cfb_imageblit, }; -struct simplefb_format { - const char *name; - u32 bits_per_pixel; - struct fb_bitfield red; - struct fb_bitfield green; - struct fb_bitfield blue; - struct fb_bitfield transp; -}; - -static struct simplefb_format simplefb_formats[] = { - { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, -}; +static struct simplefb_format simplefb_formats[] = SIMPLEFB_FORMATS; struct simplefb_params { u32 width; @@ -139,6 +129,33 @@ static int simplefb_parse_dt(struct platform_device *pdev, return 0; } +static int simplefb_parse_pd(struct platform_device *pdev, + struct simplefb_params *params) +{ + struct simplefb_platform_data *pd = pdev->dev.platform_data; + int i; + + params->width = pd->width; + params->height = pd->height; + params->stride = pd->stride; + + params->format = NULL; + for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) { + if (strcmp(pd->format, simplefb_formats[i].name)) + continue; + + params->format = &simplefb_formats[i]; + break; + } + + if (!params->format) { + dev_err(&pdev->dev, "Invalid format value\n"); + return -EINVAL; + } + + return 0; +} + static int simplefb_probe(struct platform_device *pdev) { int ret; @@ -149,7 +166,12 @@ static int simplefb_probe(struct platform_device *pdev) if (fb_get_options("simplefb", NULL)) return -ENODEV; - ret = simplefb_parse_dt(pdev, ¶ms); + ret = -ENODEV; + if (pdev->dev.platform_data) + ret = simplefb_parse_pd(pdev, ¶ms); + else if (pdev->dev.of_node) + ret = simplefb_parse_dt(pdev, ¶ms); + if (ret) return ret; @@ -180,8 +202,16 @@ static int simplefb_probe(struct platform_device *pdev) info->var.blue = params.format->blue; info->var.transp = params.format->transp; + info->apertures = alloc_apertures(1); + if (!info->apertures) { + framebuffer_release(info); + return -ENOMEM; + } + info->apertures->ranges[0].base = info->fix.smem_start; + info->apertures->ranges[0].size = info->fix.smem_len; + info->fbops = &simplefb_ops; - info->flags = FBINFO_DEFAULT; + info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE; info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, info->fix.smem_len); 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 @@ /* --------------------------------------------------------------------- */ -static struct fb_var_screeninfo vesafb_defined __initdata = { +static struct fb_var_screeninfo vesafb_defined = { .activate = FB_ACTIVATE_NOW, .height = -1, .width = -1, @@ -40,7 +40,7 @@ static struct fb_var_screeninfo vesafb_defined __initdata = { .vmode = FB_VMODE_NONINTERLACED, }; -static struct fb_fix_screeninfo vesafb_fix __initdata = { +static struct fb_fix_screeninfo vesafb_fix = { .id = "VESA VGA", .type = FB_TYPE_PACKED_PIXELS, .accel = FB_ACCEL_NONE, @@ -48,8 +48,8 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { static int inverse __read_mostly; static int mtrr __read_mostly; /* disable mtrr */ -static int vram_remap __initdata; /* Set amount of memory to be used */ -static int vram_total __initdata; /* Set total amount of memory */ +static int vram_remap; /* Set amount of memory to be used */ +static int vram_total; /* Set total amount of memory */ static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ static void (*pmi_start)(void) __read_mostly; @@ -192,7 +192,7 @@ static struct fb_ops vesafb_ops = { .fb_imageblit = cfb_imageblit, }; -static int __init vesafb_setup(char *options) +static int vesafb_setup(char *options) { char *this_opt; @@ -226,13 +226,18 @@ static int __init vesafb_setup(char *options) return 0; } -static int __init vesafb_probe(struct platform_device *dev) +static int vesafb_probe(struct platform_device *dev) { struct fb_info *info; int i, err; unsigned int size_vmode; unsigned int size_remap; unsigned int size_total; + char *option = NULL; + + /* ignore error return of fb_get_options */ + fb_get_options("vesafb", &option); + vesafb_setup(option); if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) return -ENODEV; @@ -496,40 +501,12 @@ err: } static struct platform_driver vesafb_driver = { - .driver = { - .name = "vesafb", + .driver = { + .name = "vesa-framebuffer", + .owner = THIS_MODULE, }, + .probe = vesafb_probe, }; -static struct platform_device *vesafb_device; - -static int __init vesafb_init(void) -{ - int ret; - char *option = NULL; - - /* ignore error return of fb_get_options */ - fb_get_options("vesafb", &option); - vesafb_setup(option); - - vesafb_device = platform_device_alloc("vesafb", 0); - if (!vesafb_device) - return -ENOMEM; - - ret = platform_device_add(vesafb_device); - if (!ret) { - ret = platform_driver_probe(&vesafb_driver, vesafb_probe); - if (ret) - platform_device_del(vesafb_device); - } - - if (ret) { - platform_device_put(vesafb_device); - vesafb_device = NULL; - } - - return ret; -} -module_init(vesafb_init); - +module_platform_driver(vesafb_driver); MODULE_LICENSE("GPL"); diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 6629b29a8202..84c664ea8eb9 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -259,12 +259,12 @@ static int xilinxfb_assign(struct platform_device *pdev, struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - drvdata->regs_phys = res->start; - drvdata->regs = devm_request_and_ioremap(&pdev->dev, res); - if (!drvdata->regs) { - rc = -EADDRNOTAVAIL; + drvdata->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(drvdata->regs)) { + rc = PTR_ERR(drvdata->regs); goto err_region; } + drvdata->regs_phys = res->start; } /* Allocate the framebuffer memory */ |