linux/drivers/video/mmp/panel/tpo_tj032md01bw.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/video/mmp/panel/tpo_tj032md01bw.c
   3 * active panel using spi interface to do init
   4 *
   5 * Copyright (C) 2012 Marvell Technology Group Ltd.
   6 * Authors:  Guoqing Li <ligq@marvell.com>
   7 *          Lisa Du <cldu@marvell.com>
   8 *          Zhou Zhu <zzhu3@marvell.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify it
  11 * under the terms of the GNU General Public License as published by the
  12 * Free Software Foundation; either version 2 of the License, or (at your
  13 * option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful, but WITHOUT
  16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  18 * more details.
  19 *
  20 * You should have received a copy of the GNU General Public License along with
  21 * this program.  If not, see <http://www.gnu.org/licenses/>.
  22 *
  23 */
  24
  25#include <linux/module.h>
  26#include <linux/moduleparam.h>
  27#include <linux/kernel.h>
  28#include <linux/errno.h>
  29#include <linux/string.h>
  30#include <linux/delay.h>
  31#include <linux/platform_device.h>
  32#include <linux/err.h>
  33#include <linux/spi/spi.h>
  34#include <video/mmp_disp.h>
  35
  36static u16 init[] = {
  37        0x0801,
  38        0x0800,
  39        0x0200,
  40        0x0304,
  41        0x040e,
  42        0x0903,
  43        0x0b18,
  44        0x0c53,
  45        0x0d01,
  46        0x0ee0,
  47        0x0f01,
  48        0x1058,
  49        0x201e,
  50        0x210a,
  51        0x220a,
  52        0x231e,
  53        0x2400,
  54        0x2532,
  55        0x2600,
  56        0x27ac,
  57        0x2904,
  58        0x2aa2,
  59        0x2b45,
  60        0x2c45,
  61        0x2d15,
  62        0x2e5a,
  63        0x2fff,
  64        0x306b,
  65        0x310d,
  66        0x3248,
  67        0x3382,
  68        0x34bd,
  69        0x35e7,
  70        0x3618,
  71        0x3794,
  72        0x3801,
  73        0x395d,
  74        0x3aae,
  75        0x3bff,
  76        0x07c9,
  77};
  78
  79static u16 poweroff[] = {
  80        0x07d9,
  81};
  82
  83struct tpohvga_plat_data {
  84        void (*plat_onoff)(int status);
  85        struct spi_device *spi;
  86};
  87
  88static void tpohvga_onoff(struct mmp_panel *panel, int status)
  89{
  90        struct tpohvga_plat_data *plat = panel->plat_data;
  91        int ret;
  92
  93        if (status) {
  94                plat->plat_onoff(1);
  95
  96                ret = spi_write(plat->spi, init, sizeof(init));
  97                if (ret < 0)
  98                        dev_warn(panel->dev, "init cmd failed(%d)\n", ret);
  99        } else {
 100                ret = spi_write(plat->spi, poweroff, sizeof(poweroff));
 101                if (ret < 0)
 102                        dev_warn(panel->dev, "poweroff cmd failed(%d)\n", ret);
 103
 104                plat->plat_onoff(0);
 105        }
 106}
 107
 108static struct mmp_mode mmp_modes_tpohvga[] = {
 109        [0] = {
 110                .pixclock_freq = 10394400,
 111                .refresh = 60,
 112                .xres = 320,
 113                .yres = 480,
 114                .hsync_len = 10,
 115                .left_margin = 15,
 116                .right_margin = 10,
 117                .vsync_len = 2,
 118                .upper_margin = 4,
 119                .lower_margin = 2,
 120                .invert_pixclock = 1,
 121                .pix_fmt_out = PIXFMT_RGB565,
 122        },
 123};
 124
 125static int tpohvga_get_modelist(struct mmp_panel *panel,
 126                struct mmp_mode **modelist)
 127{
 128        *modelist = mmp_modes_tpohvga;
 129        return 1;
 130}
 131
 132static struct mmp_panel panel_tpohvga = {
 133        .name = "tpohvga",
 134        .panel_type = PANELTYPE_ACTIVE,
 135        .get_modelist = tpohvga_get_modelist,
 136        .set_onoff = tpohvga_onoff,
 137};
 138
 139static int tpohvga_probe(struct spi_device *spi)
 140{
 141        struct mmp_mach_panel_info *mi;
 142        int ret;
 143        struct tpohvga_plat_data *plat_data;
 144
 145        /* get configs from platform data */
 146        mi = spi->dev.platform_data;
 147        if (mi == NULL) {
 148                dev_err(&spi->dev, "%s: no platform data defined\n", __func__);
 149                return -EINVAL;
 150        }
 151
 152        /* setup spi related info */
 153        spi->bits_per_word = 16;
 154        ret = spi_setup(spi);
 155        if (ret < 0) {
 156                dev_err(&spi->dev, "spi setup failed %d", ret);
 157                return ret;
 158        }
 159
 160        plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL);
 161        if (plat_data == NULL)
 162                return -ENOMEM;
 163
 164        plat_data->spi = spi;
 165        plat_data->plat_onoff = mi->plat_set_onoff;
 166        panel_tpohvga.plat_data = plat_data;
 167        panel_tpohvga.plat_path_name = mi->plat_path_name;
 168        panel_tpohvga.dev = &spi->dev;
 169
 170        mmp_register_panel(&panel_tpohvga);
 171
 172        return 0;
 173}
 174
 175static struct spi_driver panel_tpohvga_driver = {
 176        .driver         = {
 177                .name   = "tpo-hvga",
 178                .owner  = THIS_MODULE,
 179        },
 180        .probe          = tpohvga_probe,
 181};
 182module_spi_driver(panel_tpohvga_driver);
 183
 184MODULE_AUTHOR("Lisa Du<cldu@marvell.com>");
 185MODULE_DESCRIPTION("Panel driver for tpohvga");
 186MODULE_LICENSE("GPL");
 187