* Re: [PATCHv3][ 1/5] fbdev: Add the lacking FB_SYNC_* for matching the DISPLAY_FLAGS_*
From: Tomi Valkeinen @ 2013-10-29 10:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1382532229-32755-1-git-send-email-denis@eukrea.com>
[-- Attachment #1: Type: text/plain, Size: 2393 bytes --]
On 23/10/13 15:43, Denis Carikli wrote:
> Without that fix, drivers using the fb_videomode_from_videomode
> function will not be able to get certain information because
> some DISPLAY_FLAGS_* have no corresponding FB_SYNC_*.
>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: linux-fbdev@vger.kernel.org
> Cc: Rob Herring <rob.herring@calxeda.com>
> Cc: Pawel Moll <pawel.moll@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Stephen Warren <swarren@wwwdotorg.org>
> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
> Cc: devicetree@vger.kernel.org
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: Eric Bénard <eric@eukrea.com>
> Signed-off-by: Denis Carikli <denis@eukrea.com>
> Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
> ChangeLog v2->v3:
> - Added Jean-Christophe PLAGNIOL-VILLARD's ACK.
> ---
> drivers/video/fbmon.c | 4 ++++
> include/uapi/linux/fb.h | 2 ++
> 2 files changed, 6 insertions(+)
>
> diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
> index 6103fa6..29a9ed0 100644
> --- a/drivers/video/fbmon.c
> +++ b/drivers/video/fbmon.c
> @@ -1402,6 +1402,10 @@ int fb_videomode_from_videomode(const struct videomode *vm,
> fbmode->sync |= FB_SYNC_HOR_HIGH_ACT;
> if (vm->flags & DISPLAY_FLAGS_VSYNC_HIGH)
> fbmode->sync |= FB_SYNC_VERT_HIGH_ACT;
> + if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
> + fbmode->sync |= FB_SYNC_DE_HIGH_ACT;
> + if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
> + fbmode->sync |= FB_SYNC_PIXDAT_HIGH_ACT;
> if (vm->flags & DISPLAY_FLAGS_INTERLACED)
> fbmode->vmode |= FB_VMODE_INTERLACED;
> if (vm->flags & DISPLAY_FLAGS_DOUBLESCAN)
> diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
> index fb795c3..30487df 100644
> --- a/include/uapi/linux/fb.h
> +++ b/include/uapi/linux/fb.h
> @@ -215,6 +215,8 @@ struct fb_bitfield {
> /* vtotal = 144d/288n/576i => PAL */
> /* vtotal = 121d/242n/484i => NTSC */
> #define FB_SYNC_ON_GREEN 32 /* sync on green */
> +#define FB_SYNC_DE_HIGH_ACT 64 /* data enable high active */
> +#define FB_SYNC_PIXDAT_HIGH_ACT 64 /* data enable high active */
This can't be right. You map both flags to value 64. And the comment is
the same for both.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* Re: [PATCH v3] efifb: prevent null-deref when iterating dmi_list
From: Tomi Valkeinen @ 2013-10-29 10:42 UTC (permalink / raw)
To: David Herrmann, linux-fbdev
Cc: James Bates, linux-kernel, Jean-Christophe Plagniol-Villard
In-Reply-To: <1380732219-5458-1-git-send-email-dh.herrmann@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1731 bytes --]
On 02/10/13 19:43, David Herrmann wrote:
> From: James Bates <james.h.bates@gmail.com>
>
> The dmi_list array is initialized using gnu designated initializers, and
> therefore may contain fewer explicitly defined entries as there are
> elements in it. This is because the enum above with M_xyz constants
> contains more items than the designated initializer. Those elements not
> explicitly initialized are implicitly set to 0.
>
> Now efifb_setup() loops through all these array elements, and performs
> a strcmp on each item. For non explicitly initialized elements this will
> be a null pointer:
>
> This patch swaps the check order in the if statement, thus checks first
> whether dmi_list[i].base is null.
>
> Signed-off-by: James Bates <james.h.bates@gmail.com>
> Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
> ---
> v3: fixes the "Author" field and James' email address
>
> drivers/video/efifb.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
> index 7f9ff75..fcb9500 100644
> --- a/drivers/video/efifb.c
> +++ b/drivers/video/efifb.c
> @@ -108,8 +108,8 @@ static int efifb_setup(char *options)
> if (!*this_opt) continue;
>
> for (i = 0; i < M_UNKNOWN; i++) {
> - if (!strcmp(this_opt, efifb_dmi_list[i].optname) &&
> - efifb_dmi_list[i].base != 0) {
> + if (efifb_dmi_list[i].base != 0 &&
> + !strcmp(this_opt, efifb_dmi_list[i].optname)) {
> 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;
>
Thanks, queued for 3.13.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] framebuffer: Add fb_<level> convenience logging macros
From: Tomi Valkeinen @ 2013-10-29 10:56 UTC (permalink / raw)
To: Joe Perches, Jean-Christophe Plagniol-Villard; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <0926c7a34ac51c4cbb67debd0d883f41891e75d9.1379640011.git.joe@perches.com>
[-- Attachment #1: Type: text/plain, Size: 1287 bytes --]
On 20/09/13 04:35, Joe Perches wrote:
> Add fb_<level> convenience macros for emitting the
> "fb%d: ", struct fb_info->node value.
>
> Neatens and shortens the code a bit.
>
> Signed-off-by: Joe Perches <joe@perches.com>
> ---
> include/linux/fb.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/include/linux/fb.h b/include/linux/fb.h
> index ffac70a..70c4836 100644
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -792,4 +792,16 @@ extern int fb_find_mode(struct fb_var_screeninfo *var,
> const struct fb_videomode *default_mode,
> unsigned int default_bpp);
>
> +/* Convenience logging macros */
> +#define fb_err(fb_info, fmt, ...) \
> + pr_err("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
> +#define fb_notice(info, fmt, ...) \
> + pr_notice("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
> +#define fb_warn(fb_info, fmt, ...) \
> + pr_warn("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
> +#define fb_info(fb_info, fmt, ...) \
> + pr_info("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
> +#define fb_dbg(fb_info, fmt, ...) \
> + pr_debug("fb%d: " fmt, (fb_info)->node, ##__VA_ARGS__)
> +
> #endif /* _LINUX_FB_H */
>
Thanks, queued this and the next one for 3.13.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* Re: [PATCH v2] omapdss: Add new panel driver for Topolly td028ttec1 LCD.
From: Tomi Valkeinen @ 2013-10-29 11:07 UTC (permalink / raw)
To: Marek Belisko
Cc: plagnioj, linux-kernel, linux-omap, linux-fbdev,
H. Nikolaus Schaller
In-Reply-To: <1382019258-21000-1-git-send-email-marek@goldelico.com>
[-- Attachment #1: Type: text/plain, Size: 13761 bytes --]
On 17/10/13 17:14, Marek Belisko wrote:
> Signed-off-by: Marek Belisko <marek@goldelico.com>
> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
> ---
>
> changes from v1:
> - reworked to be spi driver instead platform with custom spi bitbang
> this configuration was tested with spi_gpio bitbang driver on gta04 board
> and works fine (thanks Tomi and Lars-Peter for comments)
> - address previous comments
>
> drivers/video/omap2/displays-new/Kconfig | 6 +
> drivers/video/omap2/displays-new/Makefile | 1 +
> .../omap2/displays-new/panel-tpo-td028ttec1.c | 486 +++++++++++++++++++++
> include/video/omap-panel-data.h | 13 +
> 4 files changed, 506 insertions(+)
> create mode 100644 drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
>
> diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
> index 6c90885..1054249 100644
> --- a/drivers/video/omap2/displays-new/Kconfig
> +++ b/drivers/video/omap2/displays-new/Kconfig
> @@ -56,6 +56,12 @@ config DISPLAY_PANEL_SHARP_LS037V7DW01
> help
> LCD Panel used in TI's SDP3430 and EVM boards
>
> +config DISPLAY_PANEL_TPO_TD028TTEC1
> + tristate "TPO TD028TTEC1 LCD Panel"
> + depends on SPI
> + help
> + LCD panel used in Openmoko.
> +
> config DISPLAY_PANEL_TPO_TD043MTEA1
> tristate "TPO TD043MTEA1 LCD Panel"
> depends on SPI
> diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
> index 5aeb11b..0323a8a 100644
> --- a/drivers/video/omap2/displays-new/Makefile
> +++ b/drivers/video/omap2/displays-new/Makefile
> @@ -8,5 +8,6 @@ obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
> obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
> obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
> obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
> +obj-$(CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
> obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
> obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
> diff --git a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
> new file mode 100644
> index 0000000..5a44d30
> --- /dev/null
> +++ b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
> @@ -0,0 +1,486 @@
> +/*
> + * Toppoly TD028TTEC1 panel support
> + *
> + * Copyright (C) 2008 Nokia Corporation
> + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
> + *
> + * Neo 1973 code (jbt6k74.c):
> + * Copyright (C) 2006-2007 by OpenMoko, Inc.
> + * Author: Harald Welte <laforge@openmoko.org>
> + *
> + * Ported and adapted from Neo 1973 U-Boot by:
> + * H. Nikolaus Schaller <hns@goldelico.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/gpio.h>
> +#include <video/omapdss.h>
> +#include <video/omap-panel-data.h>
> +
> +struct panel_drv_data {
> + struct omap_dss_device dssdev;
> + struct omap_dss_device *in;
> +
> + int data_lines;
> +
> + struct omap_video_timings videomode;
> +
> + struct spi_device *spi_dev;
> +
> + u16 tx_buf[4];
Is there some particular reason to have tx_buf in the driver data? It
looks to me that it would fit better as a local variable for the funcs
that need it.
> +};
> +
> +static struct omap_video_timings td028ttec1_panel_timings = {
> + .x_res = 480,
> + .y_res = 640,
> + .pixel_clock = 22153,
> + .hfp = 24,
> + .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_OPPOSITE_EDGES,
> +};
> +
> +#define JBT_COMMAND 0x000
> +#define JBT_DATA 0x100
> +
> +int jbt_reg_write_nodata(struct panel_drv_data *ddata, u8 reg)
> +{
> + int rc;
> +
> + ddata->tx_buf[0] = JBT_COMMAND | reg;
> + rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
> + 1*sizeof(u16));
> + if (rc != 0)
> + dev_err(&ddata->spi_dev->dev,
> + "jbt_reg_write_nodata spi_write ret %d\n", rc);
> +
> + return rc;
> +}
> +
> +int jbt_reg_write(struct panel_drv_data *ddata, u8 reg, u8 data)
Perhaps name this jbt_reg_write8 to be in line with the jbt_reg_write16.
Or is it obvious that the function without a suffix works on bytes?
Just a side note, on DSI side I have used suffixes _0, _1, _2 to
represent transmission without data, with one byte and with 2 bytes.
> +{
> + int rc;
> +
> + ddata->tx_buf[0] = JBT_COMMAND | reg;
> + ddata->tx_buf[1] = JBT_DATA | data;
> + rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
> + 2*sizeof(u16));
> + if (rc != 0)
> + dev_err(&ddata->spi_dev->dev,
> + "jbt_reg_write spi_write ret %d\n", rc);
> +
> + return rc;
> +}
> +
> +int jbt_reg_write16(struct panel_drv_data *ddata, u8 reg, u16 data)
> +{
> + int rc;
> +
> + ddata->tx_buf[0] = JBT_COMMAND | reg;
> + ddata->tx_buf[1] = JBT_DATA | (data >> 8);
> + ddata->tx_buf[2] = JBT_DATA | (data & 0xff);
> +
> + rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
> + 3*sizeof(u16));
> +
> + if (rc != 0)
> + dev_err(&ddata->spi_dev->dev,
> + "jbt_reg_write16 spi_write ret %d\n", rc);
> +
> + return rc;
> +}
> +
> +enum jbt_register {
> + JBT_REG_SLEEP_IN = 0x10,
> + JBT_REG_SLEEP_OUT = 0x11,
> +
> + JBT_REG_DISPLAY_OFF = 0x28,
> + JBT_REG_DISPLAY_ON = 0x29,
> +
> + JBT_REG_RGB_FORMAT = 0x3a,
> + JBT_REG_QUAD_RATE = 0x3b,
> +
> + JBT_REG_POWER_ON_OFF = 0xb0,
> + JBT_REG_BOOSTER_OP = 0xb1,
> + JBT_REG_BOOSTER_MODE = 0xb2,
> + JBT_REG_BOOSTER_FREQ = 0xb3,
> + JBT_REG_OPAMP_SYSCLK = 0xb4,
> + JBT_REG_VSC_VOLTAGE = 0xb5,
> + JBT_REG_VCOM_VOLTAGE = 0xb6,
> + JBT_REG_EXT_DISPL = 0xb7,
> + JBT_REG_OUTPUT_CONTROL = 0xb8,
> + JBT_REG_DCCLK_DCEV = 0xb9,
> + JBT_REG_DISPLAY_MODE1 = 0xba,
> + JBT_REG_DISPLAY_MODE2 = 0xbb,
> + JBT_REG_DISPLAY_MODE = 0xbc,
> + JBT_REG_ASW_SLEW = 0xbd,
> + JBT_REG_DUMMY_DISPLAY = 0xbe,
> + JBT_REG_DRIVE_SYSTEM = 0xbf,
> +
> + JBT_REG_SLEEP_OUT_FR_A = 0xc0,
> + JBT_REG_SLEEP_OUT_FR_B = 0xc1,
> + JBT_REG_SLEEP_OUT_FR_C = 0xc2,
> + JBT_REG_SLEEP_IN_LCCNT_D = 0xc3,
> + JBT_REG_SLEEP_IN_LCCNT_E = 0xc4,
> + JBT_REG_SLEEP_IN_LCCNT_F = 0xc5,
> + JBT_REG_SLEEP_IN_LCCNT_G = 0xc6,
> +
> + JBT_REG_GAMMA1_FINE_1 = 0xc7,
> + JBT_REG_GAMMA1_FINE_2 = 0xc8,
> + JBT_REG_GAMMA1_INCLINATION = 0xc9,
> + JBT_REG_GAMMA1_BLUE_OFFSET = 0xca,
> +
> + JBT_REG_BLANK_CONTROL = 0xcf,
> + JBT_REG_BLANK_TH_TV = 0xd0,
> + JBT_REG_CKV_ON_OFF = 0xd1,
> + JBT_REG_CKV_1_2 = 0xd2,
> + JBT_REG_OEV_TIMING = 0xd3,
> + JBT_REG_ASW_TIMING_1 = 0xd4,
> + JBT_REG_ASW_TIMING_2 = 0xd5,
> +
> + JBT_REG_HCLOCK_VGA = 0xec,
> + JBT_REG_HCLOCK_QVGA = 0xed,
> +};
> +
> +#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
> +
> +static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
> +{
> + struct panel_drv_data *ddata = to_panel_data(dssdev);
> + struct omap_dss_device *in = ddata->in;
> + int r;
> +
> + if (omapdss_device_is_connected(dssdev))
> + return 0;
> +
> + r = in->ops.dpi->connect(in, dssdev);
> + if (r)
> + return r;
> +
> + return 0;
> +}
> +
> +static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
> +{
> + struct panel_drv_data *ddata = to_panel_data(dssdev);
> + struct omap_dss_device *in = ddata->in;
> +
> + if (!omapdss_device_is_connected(dssdev))
> + return;
> +
> + in->ops.dpi->disconnect(in, dssdev);
> +}
> +
> +static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
> +{
> + struct panel_drv_data *ddata = to_panel_data(dssdev);
> + struct omap_dss_device *in = ddata->in;
> + int r;
> +
> + if (!omapdss_device_is_connected(dssdev))
> + return -ENODEV;
> +
> + if (omapdss_device_is_enabled(dssdev))
> + return 0;
> +
> + in->ops.dpi->set_data_lines(in, ddata->data_lines);
> + in->ops.dpi->set_timings(in, &ddata->videomode);
> +
> + r = in->ops.dpi->enable(in);
> + if (r)
> + return r;
> +
> + dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
> + dssdev->state);
> +
> + /*
> + * according to data sheet: wait 50ms (Tpos of LCM). However, 50ms
> + * seems unreliable with later LCM batches, increasing to 90ms
> + */
> + msleep(90);
Wait for what?
> +
> + /* three times command zero */
> + r |= jbt_reg_write_nodata(ddata, 0x00);
> + msleep(1000);
> + r |= jbt_reg_write_nodata(ddata, 0x00);
> + msleep(1000);
> + r |= jbt_reg_write_nodata(ddata, 0x00);
> + msleep(1000);
Three _seconds_? That's a huge delay when enabling a panel. Is this
really required?
> +
> + if (r) {
> + dev_warn(dssdev->dev, "transfer error\n");
> + goto transfer_err;
> + }
> +
> + /* deep standby out */
> + r |= jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x17);
> +
> + /* RGB I/F on, RAM write off, QVGA through, SIGCON enable */
> + r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE, 0x80);
> +
> + /* Quad mode off */
> + r |= jbt_reg_write(ddata, JBT_REG_QUAD_RATE, 0x00);
> +
> + /* AVDD on, XVDD on */
> + r |= jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x16);
> +
> + /* Output control */
> + r |= jbt_reg_write16(ddata, JBT_REG_OUTPUT_CONTROL, 0xfff9);
> +
> + /* Sleep mode off */
> + r |= jbt_reg_write_nodata(ddata, JBT_REG_SLEEP_OUT);
> +
> + /* at this point we have like 50% grey */
> +
> + /* initialize register set */
> + r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE1, 0x01);
> + r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE2, 0x00);
> + r |= jbt_reg_write(ddata, JBT_REG_RGB_FORMAT, 0x60);
> + r |= jbt_reg_write(ddata, JBT_REG_DRIVE_SYSTEM, 0x10);
> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_OP, 0x56);
> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_MODE, 0x33);
> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
> + r |= jbt_reg_write(ddata, JBT_REG_OPAMP_SYSCLK, 0x02);
> + r |= jbt_reg_write(ddata, JBT_REG_VSC_VOLTAGE, 0x2b);
> + r |= jbt_reg_write(ddata, JBT_REG_VCOM_VOLTAGE, 0x40);
> + r |= jbt_reg_write(ddata, JBT_REG_EXT_DISPL, 0x03);
> + r |= jbt_reg_write(ddata, JBT_REG_DCCLK_DCEV, 0x04);
> + /*
> + * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
> + * to avoid red / blue flicker
> + */
> + r |= jbt_reg_write(ddata, JBT_REG_ASW_SLEW, 0x04);
> + r |= jbt_reg_write(ddata, JBT_REG_DUMMY_DISPLAY, 0x00);
> +
> + r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_A, 0x11);
> + r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_B, 0x11);
> + r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_C, 0x11);
> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
> +
> + r |= jbt_reg_write16(ddata, JBT_REG_GAMMA1_FINE_1, 0x5533);
> + r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_FINE_2, 0x00);
> + r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_INCLINATION, 0x00);
> + r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
> +
> + r |= jbt_reg_write16(ddata, JBT_REG_HCLOCK_VGA, 0x1f0);
> + r |= jbt_reg_write(ddata, JBT_REG_BLANK_CONTROL, 0x02);
> + r |= jbt_reg_write16(ddata, JBT_REG_BLANK_TH_TV, 0x0804);
> +
> + r |= jbt_reg_write(ddata, JBT_REG_CKV_ON_OFF, 0x01);
> + r |= jbt_reg_write16(ddata, JBT_REG_CKV_1_2, 0x0000);
> +
> + r |= jbt_reg_write16(ddata, JBT_REG_OEV_TIMING, 0x0d0e);
> + r |= jbt_reg_write16(ddata, JBT_REG_ASW_TIMING_1, 0x11a4);
> + r |= jbt_reg_write(ddata, JBT_REG_ASW_TIMING_2, 0x0e);
> +
> + r |= jbt_reg_write_nodata(ddata, JBT_REG_DISPLAY_ON);
> +
> + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
> +
> +transfer_err:
> +
> + return r ? -EIO : 0;
> +}
> +
> +static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
> +{
> + struct panel_drv_data *ddata = to_panel_data(dssdev);
> + struct omap_dss_device *in = ddata->in;
> +
> + if (!omapdss_device_is_enabled(dssdev))
> + return;
> +
> + dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
> +
> + in->ops.dpi->disable(in);
> +
> + jbt_reg_write_nodata(ddata, JBT_REG_DISPLAY_OFF);
> + jbt_reg_write16(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
> + jbt_reg_write_nodata(ddata, JBT_REG_SLEEP_IN);
> + jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x00);
I don't know about this particular panel, but usually you should first
send a DISPLAY_OFF command, and only afterwards disable the DPI output.
Otherwise the panels I know will show garbage on the screen, as the
video stream has ended.
That would also be reverse of the enable sequence.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* Re: [PATCH v2] omapdss: Add new panel driver for Topolly td028ttec1 LCD.
From: Belisko Marek @ 2013-10-29 11:36 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Jean-Christophe PLAGNIOL-VILLARD, LKML,
linux-omap@vger.kernel.org, linux-fbdev, H. Nikolaus Schaller
In-Reply-To: <526F96ED.906@ti.com>
Hi Tomi,
On Tue, Oct 29, 2013 at 12:07 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On 17/10/13 17:14, Marek Belisko wrote:
>> Signed-off-by: Marek Belisko <marek@goldelico.com>
>> Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
>> ---
>>
>> changes from v1:
>> - reworked to be spi driver instead platform with custom spi bitbang
>> this configuration was tested with spi_gpio bitbang driver on gta04 board
>> and works fine (thanks Tomi and Lars-Peter for comments)
>> - address previous comments
>>
>> drivers/video/omap2/displays-new/Kconfig | 6 +
>> drivers/video/omap2/displays-new/Makefile | 1 +
>> .../omap2/displays-new/panel-tpo-td028ttec1.c | 486 +++++++++++++++++++++
>> include/video/omap-panel-data.h | 13 +
>> 4 files changed, 506 insertions(+)
>> create mode 100644 drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
>>
>> diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
>> index 6c90885..1054249 100644
>> --- a/drivers/video/omap2/displays-new/Kconfig
>> +++ b/drivers/video/omap2/displays-new/Kconfig
>> @@ -56,6 +56,12 @@ config DISPLAY_PANEL_SHARP_LS037V7DW01
>> help
>> LCD Panel used in TI's SDP3430 and EVM boards
>>
>> +config DISPLAY_PANEL_TPO_TD028TTEC1
>> + tristate "TPO TD028TTEC1 LCD Panel"
>> + depends on SPI
>> + help
>> + LCD panel used in Openmoko.
>> +
>> config DISPLAY_PANEL_TPO_TD043MTEA1
>> tristate "TPO TD043MTEA1 LCD Panel"
>> depends on SPI
>> diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
>> index 5aeb11b..0323a8a 100644
>> --- a/drivers/video/omap2/displays-new/Makefile
>> +++ b/drivers/video/omap2/displays-new/Makefile
>> @@ -8,5 +8,6 @@ obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
>> obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
>> obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
>> obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
>> +obj-$(CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
>> obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
>> obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
>> diff --git a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
>> new file mode 100644
>> index 0000000..5a44d30
>> --- /dev/null
>> +++ b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
>> @@ -0,0 +1,486 @@
>> +/*
>> + * Toppoly TD028TTEC1 panel support
>> + *
>> + * Copyright (C) 2008 Nokia Corporation
>> + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
>> + *
>> + * Neo 1973 code (jbt6k74.c):
>> + * Copyright (C) 2006-2007 by OpenMoko, Inc.
>> + * Author: Harald Welte <laforge@openmoko.org>
>> + *
>> + * Ported and adapted from Neo 1973 U-Boot by:
>> + * H. Nikolaus Schaller <hns@goldelico.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/gpio.h>
>> +#include <video/omapdss.h>
>> +#include <video/omap-panel-data.h>
>> +
>> +struct panel_drv_data {
>> + struct omap_dss_device dssdev;
>> + struct omap_dss_device *in;
>> +
>> + int data_lines;
>> +
>> + struct omap_video_timings videomode;
>> +
>> + struct spi_device *spi_dev;
>> +
>> + u16 tx_buf[4];
>
> Is there some particular reason to have tx_buf in the driver data? It
> looks to me that it would fit better as a local variable for the funcs
> that need it.
Yes that's true. I'll remove from driver data.
>
>> +};
>> +
>> +static struct omap_video_timings td028ttec1_panel_timings = {
>> + .x_res = 480,
>> + .y_res = 640,
>> + .pixel_clock = 22153,
>> + .hfp = 24,
>> + .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_OPPOSITE_EDGES,
>> +};
>> +
>> +#define JBT_COMMAND 0x000
>> +#define JBT_DATA 0x100
>> +
>> +int jbt_reg_write_nodata(struct panel_drv_data *ddata, u8 reg)
>> +{
>> + int rc;
>> +
>> + ddata->tx_buf[0] = JBT_COMMAND | reg;
>> + rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
>> + 1*sizeof(u16));
>> + if (rc != 0)
>> + dev_err(&ddata->spi_dev->dev,
>> + "jbt_reg_write_nodata spi_write ret %d\n", rc);
>> +
>> + return rc;
>> +}
>> +
>> +int jbt_reg_write(struct panel_drv_data *ddata, u8 reg, u8 data)
>
> Perhaps name this jbt_reg_write8 to be in line with the jbt_reg_write16.
> Or is it obvious that the function without a suffix works on bytes?
>
> Just a side note, on DSI side I have used suffixes _0, _1, _2 to
> represent transmission without data, with one byte and with 2 bytes.
OK sounds reasonable. I'll update.
>
>> +{
>> + int rc;
>> +
>> + ddata->tx_buf[0] = JBT_COMMAND | reg;
>> + ddata->tx_buf[1] = JBT_DATA | data;
>> + rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
>> + 2*sizeof(u16));
>> + if (rc != 0)
>> + dev_err(&ddata->spi_dev->dev,
>> + "jbt_reg_write spi_write ret %d\n", rc);
>> +
>> + return rc;
>> +}
>> +
>> +int jbt_reg_write16(struct panel_drv_data *ddata, u8 reg, u16 data)
>> +{
>> + int rc;
>> +
>> + ddata->tx_buf[0] = JBT_COMMAND | reg;
>> + ddata->tx_buf[1] = JBT_DATA | (data >> 8);
>> + ddata->tx_buf[2] = JBT_DATA | (data & 0xff);
>> +
>> + rc = spi_write(ddata->spi_dev, (u8 *)ddata->tx_buf,
>> + 3*sizeof(u16));
>> +
>> + if (rc != 0)
>> + dev_err(&ddata->spi_dev->dev,
>> + "jbt_reg_write16 spi_write ret %d\n", rc);
>> +
>> + return rc;
>> +}
>> +
>> +enum jbt_register {
>> + JBT_REG_SLEEP_IN = 0x10,
>> + JBT_REG_SLEEP_OUT = 0x11,
>> +
>> + JBT_REG_DISPLAY_OFF = 0x28,
>> + JBT_REG_DISPLAY_ON = 0x29,
>> +
>> + JBT_REG_RGB_FORMAT = 0x3a,
>> + JBT_REG_QUAD_RATE = 0x3b,
>> +
>> + JBT_REG_POWER_ON_OFF = 0xb0,
>> + JBT_REG_BOOSTER_OP = 0xb1,
>> + JBT_REG_BOOSTER_MODE = 0xb2,
>> + JBT_REG_BOOSTER_FREQ = 0xb3,
>> + JBT_REG_OPAMP_SYSCLK = 0xb4,
>> + JBT_REG_VSC_VOLTAGE = 0xb5,
>> + JBT_REG_VCOM_VOLTAGE = 0xb6,
>> + JBT_REG_EXT_DISPL = 0xb7,
>> + JBT_REG_OUTPUT_CONTROL = 0xb8,
>> + JBT_REG_DCCLK_DCEV = 0xb9,
>> + JBT_REG_DISPLAY_MODE1 = 0xba,
>> + JBT_REG_DISPLAY_MODE2 = 0xbb,
>> + JBT_REG_DISPLAY_MODE = 0xbc,
>> + JBT_REG_ASW_SLEW = 0xbd,
>> + JBT_REG_DUMMY_DISPLAY = 0xbe,
>> + JBT_REG_DRIVE_SYSTEM = 0xbf,
>> +
>> + JBT_REG_SLEEP_OUT_FR_A = 0xc0,
>> + JBT_REG_SLEEP_OUT_FR_B = 0xc1,
>> + JBT_REG_SLEEP_OUT_FR_C = 0xc2,
>> + JBT_REG_SLEEP_IN_LCCNT_D = 0xc3,
>> + JBT_REG_SLEEP_IN_LCCNT_E = 0xc4,
>> + JBT_REG_SLEEP_IN_LCCNT_F = 0xc5,
>> + JBT_REG_SLEEP_IN_LCCNT_G = 0xc6,
>> +
>> + JBT_REG_GAMMA1_FINE_1 = 0xc7,
>> + JBT_REG_GAMMA1_FINE_2 = 0xc8,
>> + JBT_REG_GAMMA1_INCLINATION = 0xc9,
>> + JBT_REG_GAMMA1_BLUE_OFFSET = 0xca,
>> +
>> + JBT_REG_BLANK_CONTROL = 0xcf,
>> + JBT_REG_BLANK_TH_TV = 0xd0,
>> + JBT_REG_CKV_ON_OFF = 0xd1,
>> + JBT_REG_CKV_1_2 = 0xd2,
>> + JBT_REG_OEV_TIMING = 0xd3,
>> + JBT_REG_ASW_TIMING_1 = 0xd4,
>> + JBT_REG_ASW_TIMING_2 = 0xd5,
>> +
>> + JBT_REG_HCLOCK_VGA = 0xec,
>> + JBT_REG_HCLOCK_QVGA = 0xed,
>> +};
>> +
>> +#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
>> +
>> +static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
>> +{
>> + struct panel_drv_data *ddata = to_panel_data(dssdev);
>> + struct omap_dss_device *in = ddata->in;
>> + int r;
>> +
>> + if (omapdss_device_is_connected(dssdev))
>> + return 0;
>> +
>> + r = in->ops.dpi->connect(in, dssdev);
>> + if (r)
>> + return r;
>> +
>> + return 0;
>> +}
>> +
>> +static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
>> +{
>> + struct panel_drv_data *ddata = to_panel_data(dssdev);
>> + struct omap_dss_device *in = ddata->in;
>> +
>> + if (!omapdss_device_is_connected(dssdev))
>> + return;
>> +
>> + in->ops.dpi->disconnect(in, dssdev);
>> +}
>> +
>> +static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
>> +{
>> + struct panel_drv_data *ddata = to_panel_data(dssdev);
>> + struct omap_dss_device *in = ddata->in;
>> + int r;
>> +
>> + if (!omapdss_device_is_connected(dssdev))
>> + return -ENODEV;
>> +
>> + if (omapdss_device_is_enabled(dssdev))
>> + return 0;
>> +
>> + in->ops.dpi->set_data_lines(in, ddata->data_lines);
>> + in->ops.dpi->set_timings(in, &ddata->videomode);
>> +
>> + r = in->ops.dpi->enable(in);
>> + if (r)
>> + return r;
>> +
>> + dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
>> + dssdev->state);
>> +
>> + /*
>> + * according to data sheet: wait 50ms (Tpos of LCM). However, 50ms
>> + * seems unreliable with later LCM batches, increasing to 90ms
>> + */
>> + msleep(90);
>
> Wait for what?
>
>> +
>> + /* three times command zero */
>> + r |= jbt_reg_write_nodata(ddata, 0x00);
>> + msleep(1000);
>> + r |= jbt_reg_write_nodata(ddata, 0x00);
>> + msleep(1000);
>> + r |= jbt_reg_write_nodata(ddata, 0x00);
>> + msleep(1000);
>
> Three _seconds_? That's a huge delay when enabling a panel. Is this
> really required?
I checked old driver and there is same but wait for 1ms only not 1 sec [1].
I'll check if 1ms will be enough.
>
>> +
>> + if (r) {
>> + dev_warn(dssdev->dev, "transfer error\n");
>> + goto transfer_err;
>> + }
>> +
>> + /* deep standby out */
>> + r |= jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x17);
>> +
>> + /* RGB I/F on, RAM write off, QVGA through, SIGCON enable */
>> + r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE, 0x80);
>> +
>> + /* Quad mode off */
>> + r |= jbt_reg_write(ddata, JBT_REG_QUAD_RATE, 0x00);
>> +
>> + /* AVDD on, XVDD on */
>> + r |= jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x16);
>> +
>> + /* Output control */
>> + r |= jbt_reg_write16(ddata, JBT_REG_OUTPUT_CONTROL, 0xfff9);
>> +
>> + /* Sleep mode off */
>> + r |= jbt_reg_write_nodata(ddata, JBT_REG_SLEEP_OUT);
>> +
>> + /* at this point we have like 50% grey */
>> +
>> + /* initialize register set */
>> + r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE1, 0x01);
>> + r |= jbt_reg_write(ddata, JBT_REG_DISPLAY_MODE2, 0x00);
>> + r |= jbt_reg_write(ddata, JBT_REG_RGB_FORMAT, 0x60);
>> + r |= jbt_reg_write(ddata, JBT_REG_DRIVE_SYSTEM, 0x10);
>> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_OP, 0x56);
>> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_MODE, 0x33);
>> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
>> + r |= jbt_reg_write(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
>> + r |= jbt_reg_write(ddata, JBT_REG_OPAMP_SYSCLK, 0x02);
>> + r |= jbt_reg_write(ddata, JBT_REG_VSC_VOLTAGE, 0x2b);
>> + r |= jbt_reg_write(ddata, JBT_REG_VCOM_VOLTAGE, 0x40);
>> + r |= jbt_reg_write(ddata, JBT_REG_EXT_DISPL, 0x03);
>> + r |= jbt_reg_write(ddata, JBT_REG_DCCLK_DCEV, 0x04);
>> + /*
>> + * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
>> + * to avoid red / blue flicker
>> + */
>> + r |= jbt_reg_write(ddata, JBT_REG_ASW_SLEW, 0x04);
>> + r |= jbt_reg_write(ddata, JBT_REG_DUMMY_DISPLAY, 0x00);
>> +
>> + r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_A, 0x11);
>> + r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_B, 0x11);
>> + r |= jbt_reg_write(ddata, JBT_REG_SLEEP_OUT_FR_C, 0x11);
>> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
>> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
>> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
>> + r |= jbt_reg_write16(ddata, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
>> +
>> + r |= jbt_reg_write16(ddata, JBT_REG_GAMMA1_FINE_1, 0x5533);
>> + r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_FINE_2, 0x00);
>> + r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_INCLINATION, 0x00);
>> + r |= jbt_reg_write(ddata, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
>> +
>> + r |= jbt_reg_write16(ddata, JBT_REG_HCLOCK_VGA, 0x1f0);
>> + r |= jbt_reg_write(ddata, JBT_REG_BLANK_CONTROL, 0x02);
>> + r |= jbt_reg_write16(ddata, JBT_REG_BLANK_TH_TV, 0x0804);
>> +
>> + r |= jbt_reg_write(ddata, JBT_REG_CKV_ON_OFF, 0x01);
>> + r |= jbt_reg_write16(ddata, JBT_REG_CKV_1_2, 0x0000);
>> +
>> + r |= jbt_reg_write16(ddata, JBT_REG_OEV_TIMING, 0x0d0e);
>> + r |= jbt_reg_write16(ddata, JBT_REG_ASW_TIMING_1, 0x11a4);
>> + r |= jbt_reg_write(ddata, JBT_REG_ASW_TIMING_2, 0x0e);
>> +
>> + r |= jbt_reg_write_nodata(ddata, JBT_REG_DISPLAY_ON);
>> +
>> + dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
>> +
>> +transfer_err:
>> +
>> + return r ? -EIO : 0;
>> +}
>> +
>> +static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
>> +{
>> + struct panel_drv_data *ddata = to_panel_data(dssdev);
>> + struct omap_dss_device *in = ddata->in;
>> +
>> + if (!omapdss_device_is_enabled(dssdev))
>> + return;
>> +
>> + dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
>> +
>> + in->ops.dpi->disable(in);
>> +
>> + jbt_reg_write_nodata(ddata, JBT_REG_DISPLAY_OFF);
>> + jbt_reg_write16(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
>> + jbt_reg_write_nodata(ddata, JBT_REG_SLEEP_IN);
>> + jbt_reg_write(ddata, JBT_REG_POWER_ON_OFF, 0x00);
>
> I don't know about this particular panel, but usually you should first
> send a DISPLAY_OFF command, and only afterwards disable the DPI output.
> Otherwise the panels I know will show garbage on the screen, as the
> video stream has ended.
>
> That would also be reverse of the enable sequence.
OK will check. Thanks.
>
> Tomi
>
>
BR,
marek
--
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer
Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
twitter: #opennandra
web: http://open-nandra.com
^ permalink raw reply
* Re: [PATCH 2/9] backlight: atmel-pwm-bl: fix gpio polarity in remove
From: Johan Hovold @ 2013-10-29 13:08 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD
Cc: Johan Hovold, Richard Purdie, Jingoo Han, Nicolas Ferre,
Tomi Valkeinen, Andrew Morton, linux-fbdev, linux-kernel, stable
In-Reply-To: <20131025110928.GR18477@ns203013.ovh.net>
On Fri, Oct 25, 2013 at 01:09:28PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 11:55 Wed 23 Oct , Johan Hovold wrote:
> > Make sure to honour gpio polarity also at remove so that the backlight
> > is actually disabled on boards with active-low enable pin.
> >
> > Cc: stable@vger.kernel.org
> > Acked-by: Jingoo Han <jg1.han@samsung.com>
> > Signed-off-by: Johan Hovold <jhovold@gmail.com>
> > ---
> > drivers/video/backlight/atmel-pwm-bl.c | 6 ++++--
> > 1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
> > index 8aac273..3cb0094 100644
> > --- a/drivers/video/backlight/atmel-pwm-bl.c
> > +++ b/drivers/video/backlight/atmel-pwm-bl.c
> > @@ -205,8 +205,10 @@ static int atmel_pwm_bl_remove(struct platform_device *pdev)
> > {
> > struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
> >
> > - if (pwmbl->gpio_on != -1)
> > - gpio_set_value(pwmbl->gpio_on, 0);
> > + if (pwmbl->gpio_on != -1) {
> here we need to use gpio_is_valid
That is a different issue which is fixed by patch 7/9. It doesn't make
sense to only change one of the gpio-validity tests.
Johan
> > + gpio_set_value(pwmbl->gpio_on,
> > + 0 ^ pwmbl->pdata->on_active_low);
> > + }
> > pwm_channel_disable(&pwmbl->pwmc);
> > pwm_channel_free(&pwmbl->pwmc);
> >
> > --
> > 1.8.4
> >
^ permalink raw reply
* Re: [PATCH 4/9] backlight: atmel-pwm-bl: clean up probe error handling
From: Johan Hovold @ 2013-10-29 13:09 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD
Cc: Johan Hovold, Richard Purdie, Jingoo Han, Nicolas Ferre,
Tomi Valkeinen, Andrew Morton, linux-fbdev, linux-kernel
In-Reply-To: <20131025111125.GS18477@ns203013.ovh.net>
On Fri, Oct 25, 2013 at 01:11:25PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 11:55 Wed 23 Oct , Johan Hovold wrote:
> > Clean up probe error handling by checking parameters before any
> > allocations and removing an obsolete error label. Also remove
> > unnecessary reset of private gpio number.
> >
> > Acked-by: Jingoo Han <jg1.han@samsung.com>
> > Signed-off-by: Johan Hovold <jhovold@gmail.com>
> > ---
> > drivers/video/backlight/atmel-pwm-bl.c | 31 ++++++++++++-------------------
> > 1 file changed, 12 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
> > index cc5a5ed..52a8134 100644
> > --- a/drivers/video/backlight/atmel-pwm-bl.c
> > +++ b/drivers/video/backlight/atmel-pwm-bl.c
> > @@ -126,40 +126,33 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
> > struct atmel_pwm_bl *pwmbl;
> > int retval;
> >
> > + pdata = dev_get_platdata(&pdev->dev);
> > + if (!pdata)
> > + return -ENODEV;
> > +
> > + if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
> > + pdata->pwm_duty_min > pdata->pwm_duty_max ||
> > + pdata->pwm_frequency = 0)
> > + return -EINVAL;
> > +
> > pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl),
> > GFP_KERNEL);
> > if (!pwmbl)
> > return -ENOMEM;
> >
> > pwmbl->pdev = pdev;
> > -
> > - pdata = dev_get_platdata(&pdev->dev);
> > - if (!pdata) {
> > - retval = -ENODEV;
> > - goto err_free_mem;
> > - }
> > -
> > - if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
> > - pdata->pwm_duty_min > pdata->pwm_duty_max ||
> > - pdata->pwm_frequency = 0) {
> > - retval = -EINVAL;
> > - goto err_free_mem;
> > - }
> > -
> > pwmbl->pdata = pdata;
> > pwmbl->gpio_on = pdata->gpio_on;
> >
> > retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
> > if (retval)
> > - goto err_free_mem;
> > + return retval;
> >
> > if (pwmbl->gpio_on != -1) {
> gpio_is_valid here
Again, this is unrelated to this patch and is fixed separately in patch
7/9.
Johan
> > retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on,
> > "gpio_atmel_pwm_bl");
> > - if (retval) {
> > - pwmbl->gpio_on = -1;
> > + if (retval)
> > goto err_free_pwm;
> > - }
> >
> > /* Turn display off by default. */
> > retval = gpio_direction_output(pwmbl->gpio_on,
> > @@ -197,7 +190,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
> >
> > err_free_pwm:
> > pwm_channel_free(&pwmbl->pwmc);
> > -err_free_mem:
> > +
> > return retval;
> > }
> >
> > --
> > 1.8.4
> >
^ permalink raw reply
* Re: [PATCH 9/9] backlight: atmel-pwm-bl: use gpio_request_one
From: Johan Hovold @ 2013-10-29 13:20 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD
Cc: Johan Hovold, Richard Purdie, Jingoo Han, Nicolas Ferre,
Tomi Valkeinen, Andrew Morton, linux-fbdev, linux-kernel
In-Reply-To: <20131025111543.GV18477@ns203013.ovh.net>
On Fri, Oct 25, 2013 at 01:15:43PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 11:55 Wed 23 Oct , Johan Hovold wrote:
> > Use devm_gpio_request_one rather than requesting and setting direction
> > in two calls.
>
> this is the same I do not see any advantage
It removes one error path.
> and as I said for ather backligth It's wrong to enable or disable it at probe
> as the bootloader might have already enable it for splash screen
I agree with you on that, and it's actually the reason for the below
clean up. I use a second patch:
if (gpio_is_valid(pwmbl->gpio_on)) {
- /* Turn display off by default. */
- if (pdata->on_active_low)
+ /* Turn display off unless already enabled. */
+ if (pdata->gpio_on_enabled ^ pdata->on_active_low)
flags = GPIOF_OUT_INIT_HIGH;
else
flags = GPIOF_OUT_INIT_LOW;
to make sure the driver does not temporarily disable the backlight at
probe.
Decided not to submit it as part of this series when I realised that
several other backlight drivers did the same, but perhaps I should?
Thanks,
Johan
> >
> > Acked-by: Jingoo Han <jg1.han@samsung.com>:w
> > Signed-off-by: Johan Hovold <jhovold@gmail.com>
> > ---
> > drivers/video/backlight/atmel-pwm-bl.c | 15 ++++++++-------
> > 1 file changed, 8 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
> > index 1277e0c..5ea2517 100644
> > --- a/drivers/video/backlight/atmel-pwm-bl.c
> > +++ b/drivers/video/backlight/atmel-pwm-bl.c
> > @@ -124,6 +124,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
> > const struct atmel_pwm_bl_platform_data *pdata;
> > struct backlight_device *bldev;
> > struct atmel_pwm_bl *pwmbl;
> > + int flags;
> > int retval;
> >
> > pdata = dev_get_platdata(&pdev->dev);
> > @@ -149,14 +150,14 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
> > return retval;
> >
> > if (gpio_is_valid(pwmbl->gpio_on)) {
> > - retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on,
> > - "gpio_atmel_pwm_bl");
> > - if (retval)
> > - goto err_free_pwm;
> > -
> > /* Turn display off by default. */
> > - retval = gpio_direction_output(pwmbl->gpio_on,
> > - 0 ^ pdata->on_active_low);
> > + if (pdata->on_active_low)
> > + flags = GPIOF_OUT_INIT_HIGH;
> > + else
> > + flags = GPIOF_OUT_INIT_LOW;
> > +
> > + retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on,
> > + flags, "gpio_atmel_pwm_bl");
> > if (retval)
> > goto err_free_pwm;
> > }
> > --
> > 1.8.4
> >
^ permalink raw reply
* Re: [PATCH 1/9] backlight: atmel-pwm-bl: fix reported brightness
From: Johan Hovold @ 2013-10-29 13:32 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD
Cc: Johan Hovold, Richard Purdie, Jingoo Han, Nicolas Ferre,
Tomi Valkeinen, Andrew Morton, linux-fbdev, linux-kernel, stable
In-Reply-To: <20131025110836.GQ18477@ns203013.ovh.net>
On Fri, Oct 25, 2013 at 01:08:36PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 11:55 Wed 23 Oct , Johan Hovold wrote:
> > The driver supports 16-bit brightness values, but the value returned
> > from get_brightness was truncated to eight bits.
> >
> > Cc: stable@vger.kernel.org
> > Acked-by: Jingoo Han <jg1.han@samsung.com>
> > Signed-off-by: Johan Hovold <jhovold@gmail.com>
> > ---
> > drivers/video/backlight/atmel-pwm-bl.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
> > index 66885fb..8aac273 100644
> > --- a/drivers/video/backlight/atmel-pwm-bl.c
> > +++ b/drivers/video/backlight/atmel-pwm-bl.c
> > @@ -70,7 +70,7 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
> > static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
> > {
> > struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
> > - u8 intensity;
> > + u32 intensity;
> >
> > if (pwmbl->pdata->pwm_active_low) {
> > intensity = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY) -
> > @@ -80,7 +80,7 @@ static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
> > pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
> > }
> >
> > - return intensity;
> > + return (u16)intensity;
> no cast mask it
Yeah, perhaps that is better. I discussed this a bit with Jingoo Han in
the thread of the original post. I'll respin.
Thanks,
Johan
> > }
> >
> > static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
> > --
> > 1.8.4
> >
^ permalink raw reply
* [PATCHv8][ 1/6] video: imxfb: Introduce regulator support.
From: Denis Carikli @ 2013-10-29 15:50 UTC (permalink / raw)
To: linux-arm-kernel
This commit is based on the following commit by Fabio Estevam:
4344429 video: mxsfb: Introduce regulator support
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
drivers/video/imxfb.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 44ee678..4bf3837 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -28,6 +28,7 @@
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/math64.h>
@@ -145,6 +146,7 @@ struct imxfb_info {
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
+ struct regulator *reg_lcd;
enum imxfb_type devtype;
bool enabled;
@@ -563,12 +565,23 @@ static void imxfb_exit_backlight(struct imxfb_info *fbi)
static void imxfb_enable_controller(struct imxfb_info *fbi)
{
+ int ret;
if (fbi->enabled)
return;
pr_debug("Enabling LCD controller\n");
+ if (fbi->reg_lcd) {
+ ret = regulator_enable(fbi->reg_lcd);
+ if (ret) {
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator enable failed with error: %d\n",
+ ret);
+ return;
+ }
+ }
+
writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
/* panning offset 0 (0 pixel offset) */
@@ -597,6 +610,8 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
static void imxfb_disable_controller(struct imxfb_info *fbi)
{
+ int ret;
+
if (!fbi->enabled)
return;
@@ -613,6 +628,14 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)
fbi->enabled = false;
writel(0, fbi->regs + LCDC_RMCR);
+
+ if (fbi->reg_lcd) {
+ ret = regulator_disable(fbi->reg_lcd);
+ if (ret)
+ dev_err(&fbi->pdev->dev,
+ "lcd regulator disable failed with error: %d\n",
+ ret);
+ }
}
static int imxfb_blank(int blank, struct fb_info *info)
@@ -1020,6 +1043,12 @@ static int imxfb_probe(struct platform_device *pdev)
goto failed_register;
}
+ fbi->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
+ if (IS_ERR(fbi->reg_lcd)) {
+ dev_info(&pdev->dev, "No lcd regulator used.\n");
+ fbi->reg_lcd = NULL;
+ }
+
imxfb_enable_controller(fbi);
fbi->pdev = pdev;
#ifdef PWMR_BACKLIGHT_AVAILABLE
--
1.7.9.5
^ permalink raw reply related
* [PATCHv8][ 2/6] video: imxfb: Also add pwmr for the device tree.
From: Denis Carikli @ 2013-10-29 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1383061860-25035-1-git-send-email-denis@eukrea.com>
pwmr has to be set to get the imxfb backlight work,
though pwmr was only configurable trough the platform data.
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Eric Bénard <eric@eukrea.com>
Signed-off-by: Denis Carikli <denis@eukrea.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Grant Likely <grant.likely@linaro.org>
---
ChangeLog v7->v8:
- Added ACKs.
---
.../devicetree/bindings/video/fsl,imx-fb.txt | 3 +++
drivers/video/imxfb.c | 2 ++
2 files changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
index 46da08d..ac457ae 100644
--- a/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
+++ b/Documentation/devicetree/bindings/video/fsl,imx-fb.txt
@@ -17,6 +17,9 @@ Required nodes:
Optional properties:
- fsl,dmacr: DMA Control Register value. This is optional. By default, the
register is not modified as recommended by the datasheet.
+- fsl,pwmr: LCDC PWM Contrast Control Register value. That property is
+ optional, but defining it is necessary to get the backlight working. If that
+ property is ommited, the register is zeroed.
- fsl,lscr1: LCDC Sharp Configuration Register value.
Example:
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 4bf3837..f09372d 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -833,6 +833,8 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)
of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr);
+ of_property_read_u32(np, "fsl,pwmr", &fbi->pwmr);
+
/* These two function pointers could be used by some specific
* platforms. */
fbi->lcd_power = NULL;
--
1.7.9.5
^ permalink raw reply related
* [PATCHv8][ 3/6] video: Kconfig: Allow more broad selection of the imxfb framebuffer driver.
From: Denis Carikli @ 2013-10-29 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1383061860-25035-1-git-send-email-denis@eukrea.com>
Without that patch, a user can't select the imxfb driver when the i.MX25 and/or
the i.MX27 device tree board are selected and that no boards that selects
IMX_HAVE_PLATFORM_IMX_FB are compiled in.
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: devicetree@vger.kernel.org
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Cc: Eric Bénard <eric@eukrea.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Denis Carikli <denis@eukrea.com>
---
ChangeLog v7->v8:
- Added ACKs.
- Add some CC(Framebuffer maintainers and mailing lists).
- Improved commit message summary.
---
drivers/video/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4f2e1b3..22adaee 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -363,7 +363,7 @@ config FB_SA1100
config FB_IMX
tristate "Freescale i.MX1/21/25/27 LCD support"
- depends on FB && IMX_HAVE_PLATFORM_IMX_FB
+ depends on FB && ARCH_MXC
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 0/9] backlight: atmel-pwm-bl: fixes and clean ups
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1382522143-32072-1-git-send-email-jhovold@gmail.com>
These patches fix a few issues and clean up the atmel-pwm-bl driver
somewhat.
Acks from Jingoo Han retained on all patches but the slightly modified
first patch.
Johan
v2:
- mask returned brightness rather than cast it to u16 (patch 1/9)
Johan Hovold (9):
backlight: atmel-pwm-bl: fix reported brightness
backlight: atmel-pwm-bl: fix gpio polarity in remove
backlight: atmel-pwm-bl: fix module autoload
backlight: atmel-pwm-bl: clean up probe error handling
backlight: atmel-pwm-bl: clean up get_intensity
backlight: atmel-pwm-bl: remove unused include
backlight: atmel-pwm-bl: use gpio_is_valid
backlight: atmel-pwm-bl: refactor gpio_on handling
backlight: atmel-pwm-bl: use gpio_request_one
drivers/video/backlight/atmel-pwm-bl.c | 86 ++++++++++++++++------------------
1 file changed, 40 insertions(+), 46 deletions(-)
--
1.8.4.2
^ permalink raw reply
* [PATCH v2 1/9] backlight: atmel-pwm-bl: fix reported brightness
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold, stable
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
The driver supports 16-bit brightness values, but the value returned
from get_brightness was truncated to eight bits.
Cc: stable@vger.kernel.org
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index 66885fb..0971a8e 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -70,7 +70,7 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
{
struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
- u8 intensity;
+ u32 intensity;
if (pwmbl->pdata->pwm_active_low) {
intensity = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY) -
@@ -80,7 +80,7 @@ static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
}
- return intensity;
+ return intensity & 0xffff;
}
static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 2/9] backlight: atmel-pwm-bl: fix gpio polarity in remove
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold, stable
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Make sure to honour gpio polarity also at remove so that the backlight
is actually disabled on boards with active-low enable pin.
Cc: stable@vger.kernel.org
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index 0971a8e..e21beb6 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -205,8 +205,10 @@ static int atmel_pwm_bl_remove(struct platform_device *pdev)
{
struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
- if (pwmbl->gpio_on != -1)
- gpio_set_value(pwmbl->gpio_on, 0);
+ if (pwmbl->gpio_on != -1) {
+ gpio_set_value(pwmbl->gpio_on,
+ 0 ^ pwmbl->pdata->on_active_low);
+ }
pwm_channel_disable(&pwmbl->pwmc);
pwm_channel_free(&pwmbl->pwmc);
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 3/9] backlight: atmel-pwm-bl: fix module autoload
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Add missing module alias which is needed for module autoloading.
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index e21beb6..4886028 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -229,3 +229,4 @@ module_platform_driver(atmel_pwm_bl_driver);
MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
MODULE_DESCRIPTION("Atmel PWM backlight driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:atmel-pwm-bl");
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 4/9] backlight: atmel-pwm-bl: clean up probe error handling
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Clean up probe error handling by checking parameters before any
allocations and removing an obsolete error label. Also remove
unnecessary reset of private gpio number.
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 31 ++++++++++++-------------------
1 file changed, 12 insertions(+), 19 deletions(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index 4886028..01af5c2 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -126,40 +126,33 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
struct atmel_pwm_bl *pwmbl;
int retval;
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata)
+ return -ENODEV;
+
+ if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
+ pdata->pwm_duty_min > pdata->pwm_duty_max ||
+ pdata->pwm_frequency = 0)
+ return -EINVAL;
+
pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl),
GFP_KERNEL);
if (!pwmbl)
return -ENOMEM;
pwmbl->pdev = pdev;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- retval = -ENODEV;
- goto err_free_mem;
- }
-
- if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
- pdata->pwm_duty_min > pdata->pwm_duty_max ||
- pdata->pwm_frequency = 0) {
- retval = -EINVAL;
- goto err_free_mem;
- }
-
pwmbl->pdata = pdata;
pwmbl->gpio_on = pdata->gpio_on;
retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
if (retval)
- goto err_free_mem;
+ return retval;
if (pwmbl->gpio_on != -1) {
retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on,
"gpio_atmel_pwm_bl");
- if (retval) {
- pwmbl->gpio_on = -1;
+ if (retval)
goto err_free_pwm;
- }
/* Turn display off by default. */
retval = gpio_direction_output(pwmbl->gpio_on,
@@ -197,7 +190,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
err_free_pwm:
pwm_channel_free(&pwmbl->pwmc);
-err_free_mem:
+
return retval;
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 5/9] backlight: atmel-pwm-bl: clean up get_intensity
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Clean up get_intensity to increase readability.
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index 01af5c2..abfaada 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -70,15 +70,14 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
{
struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
+ u32 cdty;
u32 intensity;
- if (pwmbl->pdata->pwm_active_low) {
- intensity = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY) -
- pwmbl->pdata->pwm_duty_min;
- } else {
- intensity = pwmbl->pdata->pwm_duty_max -
- pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
- }
+ cdty = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
+ if (pwmbl->pdata->pwm_active_low)
+ intensity = cdty - pwmbl->pdata->pwm_duty_min;
+ else
+ intensity = pwmbl->pdata->pwm_duty_max - cdty;
return intensity & 0xffff;
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 6/9] backlight: atmel-pwm-bl: remove unused include
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Remove unused include of clk.h.
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index abfaada..bfd6a96 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
-#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/backlight.h>
#include <linux/atmel_pwm.h>
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 7/9] backlight: atmel-pwm-bl: use gpio_is_valid
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Use gpio_is_valid rather than open coding the more restrictive != -1
test.
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index bfd6a96..c254209 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -48,7 +48,7 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
pwm_duty = pwmbl->pdata->pwm_duty_min;
if (!intensity) {
- if (pwmbl->gpio_on != -1) {
+ if (gpio_is_valid(pwmbl->gpio_on)) {
gpio_set_value(pwmbl->gpio_on,
0 ^ pwmbl->pdata->on_active_low);
}
@@ -57,7 +57,7 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
} else {
pwm_channel_enable(&pwmbl->pwmc);
pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
- if (pwmbl->gpio_on != -1) {
+ if (gpio_is_valid(pwmbl->gpio_on)) {
gpio_set_value(pwmbl->gpio_on,
1 ^ pwmbl->pdata->on_active_low);
}
@@ -146,7 +146,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
if (retval)
return retval;
- if (pwmbl->gpio_on != -1) {
+ if (gpio_is_valid(pwmbl->gpio_on)) {
retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on,
"gpio_atmel_pwm_bl");
if (retval)
@@ -196,7 +196,7 @@ static int atmel_pwm_bl_remove(struct platform_device *pdev)
{
struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
- if (pwmbl->gpio_on != -1) {
+ if (gpio_is_valid(pwmbl->gpio_on)) {
gpio_set_value(pwmbl->gpio_on,
0 ^ pwmbl->pdata->on_active_low);
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 8/9] backlight: atmel-pwm-bl: refactor gpio_on handling
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Add helper function to control the gpio_on signal.
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index c254209..bd1ed34 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -26,6 +26,14 @@ struct atmel_pwm_bl {
int gpio_on;
};
+static void atmel_pwm_bl_set_gpio_on(struct atmel_pwm_bl *pwmbl, int on)
+{
+ if (!gpio_is_valid(pwmbl->gpio_on))
+ return;
+
+ gpio_set_value(pwmbl->gpio_on, on ^ pwmbl->pdata->on_active_low);
+}
+
static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
{
struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
@@ -48,19 +56,13 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
pwm_duty = pwmbl->pdata->pwm_duty_min;
if (!intensity) {
- if (gpio_is_valid(pwmbl->gpio_on)) {
- gpio_set_value(pwmbl->gpio_on,
- 0 ^ pwmbl->pdata->on_active_low);
- }
+ atmel_pwm_bl_set_gpio_on(pwmbl, 0);
pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
pwm_channel_disable(&pwmbl->pwmc);
} else {
pwm_channel_enable(&pwmbl->pwmc);
pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
- if (gpio_is_valid(pwmbl->gpio_on)) {
- gpio_set_value(pwmbl->gpio_on,
- 1 ^ pwmbl->pdata->on_active_low);
- }
+ atmel_pwm_bl_set_gpio_on(pwmbl, 1);
}
return 0;
@@ -196,10 +198,7 @@ static int atmel_pwm_bl_remove(struct platform_device *pdev)
{
struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
- if (gpio_is_valid(pwmbl->gpio_on)) {
- gpio_set_value(pwmbl->gpio_on,
- 0 ^ pwmbl->pdata->on_active_low);
- }
+ atmel_pwm_bl_set_gpio_on(pwmbl, 0);
pwm_channel_disable(&pwmbl->pwmc);
pwm_channel_free(&pwmbl->pwmc);
--
1.8.4.2
^ permalink raw reply related
* [PATCH v2 9/9] backlight: atmel-pwm-bl: use gpio_request_one
From: Johan Hovold @ 2013-10-29 16:27 UTC (permalink / raw)
To: Richard Purdie, Jingoo Han
Cc: Nicolas Ferre, Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
Andrew Morton, linux-fbdev, linux-kernel, Johan Hovold
In-Reply-To: <1383064064-4983-1-git-send-email-jhovold@gmail.com>
Use devm_gpio_request_one rather than requesting and setting direction
in two calls.
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
---
drivers/video/backlight/atmel-pwm-bl.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
index bd1ed34..03b5f3b 100644
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -124,6 +124,7 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
const struct atmel_pwm_bl_platform_data *pdata;
struct backlight_device *bldev;
struct atmel_pwm_bl *pwmbl;
+ int flags;
int retval;
pdata = dev_get_platdata(&pdev->dev);
@@ -149,14 +150,14 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
return retval;
if (gpio_is_valid(pwmbl->gpio_on)) {
- retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on,
- "gpio_atmel_pwm_bl");
- if (retval)
- goto err_free_pwm;
-
/* Turn display off by default. */
- retval = gpio_direction_output(pwmbl->gpio_on,
- 0 ^ pdata->on_active_low);
+ if (pdata->on_active_low)
+ flags = GPIOF_OUT_INIT_HIGH;
+ else
+ flags = GPIOF_OUT_INIT_LOW;
+
+ retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on,
+ flags, "gpio_atmel_pwm_bl");
if (retval)
goto err_free_pwm;
}
--
1.8.4.2
^ permalink raw reply related
* [PATCH v3] omapdss: Add new panel driver for Topolly td028ttec1 LCD.
From: Marek Belisko @ 2013-10-29 22:25 UTC (permalink / raw)
To: tomi.valkeinen, plagnioj
Cc: hns, linux-kernel, linux-omap, linux-fbdev, Marek Belisko
Signed-off-by: Marek Belisko <marek@goldelico.com>
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
---
changes from v2:
- move tx_buf from driver data to functions where it's used
- update write functions names (to reflect how many bytes are transferred)
- update delays from 1s to 1ms (probably typo)
- remove unnecessary 90ms sleep (tested and works fine)
- disable dpi output after disable panel
changes from v1:
- reworked to be spi driver instead platform with custom spi bitbang
this configuration was tested with spi_gpio bitbang driver on gta04 board
and works fine (thanks Tomi and Lars-Peter for comments)
- address previous comments
drivers/video/omap2/displays-new/Kconfig | 6 +
drivers/video/omap2/displays-new/Makefile | 1 +
.../omap2/displays-new/panel-tpo-td028ttec1.c | 480 +++++++++++++++++++++
include/video/omap-panel-data.h | 13 +
4 files changed, 500 insertions(+)
create mode 100644 drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig
index 10b25e7..e6cfc38 100644
--- a/drivers/video/omap2/displays-new/Kconfig
+++ b/drivers/video/omap2/displays-new/Kconfig
@@ -57,6 +57,12 @@ config DISPLAY_PANEL_SHARP_LS037V7DW01
help
LCD Panel used in TI's SDP3430 and EVM boards
+config DISPLAY_PANEL_TPO_TD028TTEC1
+ tristate "TPO TD028TTEC1 LCD Panel"
+ depends on SPI
+ help
+ LCD panel used in Openmoko.
+
config DISPLAY_PANEL_TPO_TD043MTEA1
tristate "TPO TD043MTEA1 LCD Panel"
depends on SPI
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile
index 5aeb11b..0323a8a 100644
--- a/drivers/video/omap2/displays-new/Makefile
+++ b/drivers/video/omap2/displays-new/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o
obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
+obj-$(CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
new file mode 100644
index 0000000..ca77721
--- /dev/null
+++ b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -0,0 +1,480 @@
+/*
+ * Toppoly TD028TTEC1 panel support
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Neo 1973 code (jbt6k74.c):
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * Ported and adapted from Neo 1973 U-Boot by:
+ * H. Nikolaus Schaller <hns@goldelico.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/gpio.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-data.h>
+
+struct panel_drv_data {
+ struct omap_dss_device dssdev;
+ struct omap_dss_device *in;
+
+ int data_lines;
+
+ struct omap_video_timings videomode;
+
+ struct spi_device *spi_dev;
+};
+
+static struct omap_video_timings td028ttec1_panel_timings = {
+ .x_res = 480,
+ .y_res = 640,
+ .pixel_clock = 22153,
+ .hfp = 24,
+ .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_OPPOSITE_EDGES,
+};
+
+#define JBT_COMMAND 0x000
+#define JBT_DATA 0x100
+
+int jbt_ret_write_0(struct panel_drv_data *ddata, u8 reg)
+{
+ int rc;
+ u16 tx_buf = JBT_COMMAND | reg;
+
+ rc = spi_write(ddata->spi_dev, (u8 *)&tx_buf,
+ 1*sizeof(u16));
+ if (rc != 0)
+ dev_err(&ddata->spi_dev->dev,
+ "jbt_ret_write_0 spi_write ret %d\n", rc);
+
+ return rc;
+}
+
+int jbt_reg_write_1(struct panel_drv_data *ddata, u8 reg, u8 data)
+{
+ int rc;
+ u16 tx_buf[2];
+
+ tx_buf[0] = JBT_COMMAND | reg;
+ tx_buf[1] = JBT_DATA | data;
+ rc = spi_write(ddata->spi_dev, (u8 *)tx_buf,
+ 2*sizeof(u16));
+ if (rc != 0)
+ dev_err(&ddata->spi_dev->dev,
+ "jbt_reg_write_1 spi_write ret %d\n", rc);
+
+ return rc;
+}
+
+int jbt_reg_write_2(struct panel_drv_data *ddata, u8 reg, u16 data)
+{
+ int rc;
+ u16 tx_buf[3];
+
+ tx_buf[0] = JBT_COMMAND | reg;
+ tx_buf[1] = JBT_DATA | (data >> 8);
+ tx_buf[2] = JBT_DATA | (data & 0xff);
+
+ rc = spi_write(ddata->spi_dev, (u8 *)tx_buf,
+ 3*sizeof(u16));
+
+ if (rc != 0)
+ dev_err(&ddata->spi_dev->dev,
+ "jbt_reg_write_2 spi_write ret %d\n", rc);
+
+ return rc;
+}
+
+enum jbt_register {
+ JBT_REG_SLEEP_IN = 0x10,
+ JBT_REG_SLEEP_OUT = 0x11,
+
+ JBT_REG_DISPLAY_OFF = 0x28,
+ JBT_REG_DISPLAY_ON = 0x29,
+
+ JBT_REG_RGB_FORMAT = 0x3a,
+ JBT_REG_QUAD_RATE = 0x3b,
+
+ JBT_REG_POWER_ON_OFF = 0xb0,
+ JBT_REG_BOOSTER_OP = 0xb1,
+ JBT_REG_BOOSTER_MODE = 0xb2,
+ JBT_REG_BOOSTER_FREQ = 0xb3,
+ JBT_REG_OPAMP_SYSCLK = 0xb4,
+ JBT_REG_VSC_VOLTAGE = 0xb5,
+ JBT_REG_VCOM_VOLTAGE = 0xb6,
+ JBT_REG_EXT_DISPL = 0xb7,
+ JBT_REG_OUTPUT_CONTROL = 0xb8,
+ JBT_REG_DCCLK_DCEV = 0xb9,
+ JBT_REG_DISPLAY_MODE1 = 0xba,
+ JBT_REG_DISPLAY_MODE2 = 0xbb,
+ JBT_REG_DISPLAY_MODE = 0xbc,
+ JBT_REG_ASW_SLEW = 0xbd,
+ JBT_REG_DUMMY_DISPLAY = 0xbe,
+ JBT_REG_DRIVE_SYSTEM = 0xbf,
+
+ JBT_REG_SLEEP_OUT_FR_A = 0xc0,
+ JBT_REG_SLEEP_OUT_FR_B = 0xc1,
+ JBT_REG_SLEEP_OUT_FR_C = 0xc2,
+ JBT_REG_SLEEP_IN_LCCNT_D = 0xc3,
+ JBT_REG_SLEEP_IN_LCCNT_E = 0xc4,
+ JBT_REG_SLEEP_IN_LCCNT_F = 0xc5,
+ JBT_REG_SLEEP_IN_LCCNT_G = 0xc6,
+
+ JBT_REG_GAMMA1_FINE_1 = 0xc7,
+ JBT_REG_GAMMA1_FINE_2 = 0xc8,
+ JBT_REG_GAMMA1_INCLINATION = 0xc9,
+ JBT_REG_GAMMA1_BLUE_OFFSET = 0xca,
+
+ JBT_REG_BLANK_CONTROL = 0xcf,
+ JBT_REG_BLANK_TH_TV = 0xd0,
+ JBT_REG_CKV_ON_OFF = 0xd1,
+ JBT_REG_CKV_1_2 = 0xd2,
+ JBT_REG_OEV_TIMING = 0xd3,
+ JBT_REG_ASW_TIMING_1 = 0xd4,
+ JBT_REG_ASW_TIMING_2 = 0xd5,
+
+ JBT_REG_HCLOCK_VGA = 0xec,
+ JBT_REG_HCLOCK_QVGA = 0xed,
+};
+
+#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
+
+static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (omapdss_device_is_connected(dssdev))
+ return 0;
+
+ r = in->ops.dpi->connect(in, dssdev);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_connected(dssdev))
+ return;
+
+ in->ops.dpi->disconnect(in, dssdev);
+}
+
+static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+ int r;
+
+ if (!omapdss_device_is_connected(dssdev))
+ return -ENODEV;
+
+ if (omapdss_device_is_enabled(dssdev))
+ return 0;
+
+ in->ops.dpi->set_data_lines(in, ddata->data_lines);
+ in->ops.dpi->set_timings(in, &ddata->videomode);
+
+ r = in->ops.dpi->enable(in);
+ if (r)
+ return r;
+
+ dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
+ dssdev->state);
+
+ /* three times command zero */
+ r |= jbt_ret_write_0(ddata, 0x00);
+ usleep_range(1000, 2000);
+ r |= jbt_ret_write_0(ddata, 0x00);
+ usleep_range(1000, 2000);
+ r |= jbt_ret_write_0(ddata, 0x00);
+ usleep_range(1000, 2000);
+
+ if (r) {
+ dev_warn(dssdev->dev, "transfer error\n");
+ goto transfer_err;
+ }
+
+ /* deep standby out */
+ r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x17);
+
+ /* RGB I/F on, RAM write off, QVGA through, SIGCON enable */
+ r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE, 0x80);
+
+ /* Quad mode off */
+ r |= jbt_reg_write_1(ddata, JBT_REG_QUAD_RATE, 0x00);
+
+ /* AVDD on, XVDD on */
+ r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x16);
+
+ /* Output control */
+ r |= jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0xfff9);
+
+ /* Sleep mode off */
+ r |= jbt_ret_write_0(ddata, JBT_REG_SLEEP_OUT);
+
+ /* at this point we have like 50% grey */
+
+ /* initialize register set */
+ r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE1, 0x01);
+ r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE2, 0x00);
+ r |= jbt_reg_write_1(ddata, JBT_REG_RGB_FORMAT, 0x60);
+ r |= jbt_reg_write_1(ddata, JBT_REG_DRIVE_SYSTEM, 0x10);
+ r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_OP, 0x56);
+ r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_MODE, 0x33);
+ r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
+ r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11);
+ r |= jbt_reg_write_1(ddata, JBT_REG_OPAMP_SYSCLK, 0x02);
+ r |= jbt_reg_write_1(ddata, JBT_REG_VSC_VOLTAGE, 0x2b);
+ r |= jbt_reg_write_1(ddata, JBT_REG_VCOM_VOLTAGE, 0x40);
+ r |= jbt_reg_write_1(ddata, JBT_REG_EXT_DISPL, 0x03);
+ r |= jbt_reg_write_1(ddata, JBT_REG_DCCLK_DCEV, 0x04);
+ /*
+ * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement
+ * to avoid red / blue flicker
+ */
+ r |= jbt_reg_write_1(ddata, JBT_REG_ASW_SLEW, 0x04);
+ r |= jbt_reg_write_1(ddata, JBT_REG_DUMMY_DISPLAY, 0x00);
+
+ r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_A, 0x11);
+ r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_B, 0x11);
+ r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_C, 0x11);
+ r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040);
+ r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0);
+ r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020);
+ r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0);
+
+ r |= jbt_reg_write_2(ddata, JBT_REG_GAMMA1_FINE_1, 0x5533);
+ r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_FINE_2, 0x00);
+ r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_INCLINATION, 0x00);
+ r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00);
+
+ r |= jbt_reg_write_2(ddata, JBT_REG_HCLOCK_VGA, 0x1f0);
+ r |= jbt_reg_write_1(ddata, JBT_REG_BLANK_CONTROL, 0x02);
+ r |= jbt_reg_write_2(ddata, JBT_REG_BLANK_TH_TV, 0x0804);
+
+ r |= jbt_reg_write_1(ddata, JBT_REG_CKV_ON_OFF, 0x01);
+ r |= jbt_reg_write_2(ddata, JBT_REG_CKV_1_2, 0x0000);
+
+ r |= jbt_reg_write_2(ddata, JBT_REG_OEV_TIMING, 0x0d0e);
+ r |= jbt_reg_write_2(ddata, JBT_REG_ASW_TIMING_1, 0x11a4);
+ r |= jbt_reg_write_1(ddata, JBT_REG_ASW_TIMING_2, 0x0e);
+
+ r |= jbt_ret_write_0(ddata, JBT_REG_DISPLAY_ON);
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+transfer_err:
+
+ return r ? -EIO : 0;
+}
+
+static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ if (!omapdss_device_is_enabled(dssdev))
+ return;
+
+ dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
+
+ jbt_ret_write_0(ddata, JBT_REG_DISPLAY_OFF);
+ jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
+ jbt_ret_write_0(ddata, JBT_REG_SLEEP_IN);
+ jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x00);
+
+ in->ops.dpi->disable(in);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static void td028ttec1_panel_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ ddata->videomode = *timings;
+ dssdev->panel.timings = *timings;
+
+ in->ops.dpi->set_timings(in, timings);
+}
+
+static void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+
+ *timings = ddata->videomode;
+}
+
+static int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct panel_drv_data *ddata = to_panel_data(dssdev);
+ struct omap_dss_device *in = ddata->in;
+
+ return in->ops.dpi->check_timings(in, timings);
+}
+
+static struct omap_dss_driver td028ttec1_ops = {
+ .connect = td028ttec1_panel_connect,
+ .disconnect = td028ttec1_panel_disconnect,
+
+ .enable = td028ttec1_panel_enable,
+ .disable = td028ttec1_panel_disable,
+
+ .set_timings = td028ttec1_panel_set_timings,
+ .get_timings = td028ttec1_panel_get_timings,
+ .check_timings = td028ttec1_panel_check_timings,
+};
+
+static int td028ttec1_panel_probe_pdata(struct spi_device *spi)
+{
+ const struct panel_tpo_td028ttec1_platform_data *pdata;
+ struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+ struct omap_dss_device *dssdev, *in;
+
+ pdata = dev_get_platdata(&spi->dev);
+
+ in = omap_dss_find_output(pdata->source);
+ if (in = NULL) {
+ dev_err(&spi->dev, "failed to find video source '%s'\n",
+ pdata->source);
+ return -EPROBE_DEFER;
+ }
+
+ ddata->in = in;
+
+ ddata->data_lines = pdata->data_lines;
+
+ dssdev = &ddata->dssdev;
+ dssdev->name = pdata->name;
+
+ return 0;
+}
+
+static int td028ttec1_panel_probe(struct spi_device *spi)
+{
+ struct panel_drv_data *ddata;
+ struct omap_dss_device *dssdev;
+ int r;
+
+ dev_dbg(&spi->dev, "%s\n", __func__);
+
+ spi->bits_per_word = 9;
+ spi->mode = SPI_MODE_3;
+
+ r = spi_setup(spi);
+ if (r < 0) {
+ dev_err(&spi->dev, "spi_setup failed: %d\n", r);
+ return r;
+ }
+
+ ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
+ if (ddata = NULL)
+ return -ENOMEM;
+
+ dev_set_drvdata(&spi->dev, ddata);
+
+ ddata->spi_dev = spi;
+
+ if (dev_get_platdata(&spi->dev)) {
+ r = td028ttec1_panel_probe_pdata(spi);
+ if (r)
+ return r;
+ } else {
+ return -ENODEV;
+ }
+
+ ddata->videomode = td028ttec1_panel_timings;
+
+ dssdev = &ddata->dssdev;
+ dssdev->dev = &spi->dev;
+ dssdev->driver = &td028ttec1_ops;
+ dssdev->type = OMAP_DISPLAY_TYPE_DPI;
+ dssdev->owner = THIS_MODULE;
+ dssdev->panel.timings = ddata->videomode;
+ dssdev->phy.dpi.data_lines = ddata->data_lines;
+
+ r = omapdss_register_display(dssdev);
+ if (r) {
+ dev_err(&spi->dev, "Failed to register panel\n");
+ goto err_reg;
+ }
+
+ return 0;
+
+err_reg:
+ omap_dss_put_device(ddata->in);
+ return r;
+}
+
+static int td028ttec1_panel_remove(struct spi_device *spi)
+{
+ struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
+ struct omap_dss_device *dssdev = &ddata->dssdev;
+ struct omap_dss_device *in = ddata->in;
+
+ dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
+
+ omapdss_unregister_display(dssdev);
+
+ td028ttec1_panel_disable(dssdev);
+ td028ttec1_panel_disconnect(dssdev);
+
+ omap_dss_put_device(in);
+
+ return 0;
+}
+
+static struct spi_driver td028ttec1_spi_driver = {
+ .probe = td028ttec1_panel_probe,
+ .remove = td028ttec1_panel_remove,
+
+ .driver = {
+ .name = "panel-tpo-td028ttec1",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_spi_driver(td028ttec1_spi_driver);
+
+MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
+MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver");
+MODULE_LICENSE("GPL");
diff --git a/include/video/omap-panel-data.h b/include/video/omap-panel-data.h
index f7ac8d9..69279c0 100644
--- a/include/video/omap-panel-data.h
+++ b/include/video/omap-panel-data.h
@@ -238,4 +238,17 @@ struct panel_nec_nl8048hl11_platform_data {
int qvga_gpio;
};
+/**
+ * panel-tpo-td028ttec1 platform data
+ * @name: name for display entity
+ * @source: name of the display entity used as a video source
+ * @data_lines: number of DPI datalines
+ */
+struct panel_tpo_td028ttec1_platform_data {
+ const char *name;
+ const char *source;
+
+ int data_lines;
+};
+
#endif /* __OMAP_PANEL_DATA_H */
--
1.8.1.2
^ permalink raw reply related
* [PATCH v2 19/19] fbdev: sh-mobile-lcdcfb: Enable the driver on all ARM platforms
From: Laurent Pinchart @ 2013-10-29 22:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1383086274-11049-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
Renesas ARM platforms are transitioning from single-platform to
multi-platform kernels using the new ARCH_SHMOBILE_MULTI. Make the
driver available on all ARM platforms to enable it on both ARCH_SHMOBILE
and ARCH_SHMOBILE_MULTI, and increase build testing coverage with
COMPILE_TEST.
Cc: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-fbdev@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/video/Kconfig | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 84b685f..32b5c86 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -10,7 +10,7 @@ config HAVE_FB_ATMEL
config SH_MIPI_DSI
tristate
- depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+ depends on (SUPERH || ARM || COMPILE_TEST) && HAVE_CLK
config SH_LCD_MIPI_DSI
bool
@@ -1995,7 +1995,7 @@ config FB_W100
config FB_SH_MOBILE_LCDC
tristate "SuperH Mobile LCDC framebuffer support"
- depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+ depends on FB && (SUPERH || ARM || COMPILE_TEST) && HAVE_CLK
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
@@ -2482,7 +2482,7 @@ endif
config FB_SH_MOBILE_MERAM
tristate "SuperH Mobile MERAM read ahead support"
- depends on (SUPERH || ARCH_SHMOBILE)
+ depends on (SUPERH || ARM || COMPILE_TEST)
select GENERIC_ALLOCATOR
---help---
Enable MERAM support for the SuperH controller.
--
1.8.1.5
^ permalink raw reply related
* Re: [PATCH 1/1] video: exynos_mipi_dsi: Remove unused variable
From: Greg Kroah-Hartman @ 2013-10-29 23:00 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1382333533-32740-1-git-send-email-sachin.kamat@linaro.org>
On Fri, Oct 25, 2013 at 10:51:48AM +0530, Sachin Kamat wrote:
> On 24 October 2013 21:25, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> > On Monday 21 October 2013 11:02 AM, Sachin Kamat wrote:
> >> 'pdev' is not used anymore (Removed vide commit 7e0be9f9 "video:
> >> exynos_mipi_dsim: Use the generic PHY driver"). Remove it and
> >> silence the following compilation warning:
> >> drivers/video/exynos/exynos_mipi_dsi.c:144:26: warning:
> >> unused variable ‘pdev’ [-Wunused-variable]
> >>
> >> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> > Reviewed-by: Kishon Vijay Abraham I <kishon@ti.com>
>
> Thanks Kishon.
>
> I believe this patch should go through Greg's tree as your other
> patches are lined up there?
I don't take drivers/video/* patches now, am I?
greg k-h
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox