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