0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/moduleparam.h>
0014 #include <linux/kernel.h>
0015 #include <linux/errno.h>
0016 #include <linux/string.h>
0017 #include <linux/delay.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/err.h>
0020 #include <linux/spi/spi.h>
0021 #include <video/mmp_disp.h>
0022
0023 static u16 init[] = {
0024 0x0801,
0025 0x0800,
0026 0x0200,
0027 0x0304,
0028 0x040e,
0029 0x0903,
0030 0x0b18,
0031 0x0c53,
0032 0x0d01,
0033 0x0ee0,
0034 0x0f01,
0035 0x1058,
0036 0x201e,
0037 0x210a,
0038 0x220a,
0039 0x231e,
0040 0x2400,
0041 0x2532,
0042 0x2600,
0043 0x27ac,
0044 0x2904,
0045 0x2aa2,
0046 0x2b45,
0047 0x2c45,
0048 0x2d15,
0049 0x2e5a,
0050 0x2fff,
0051 0x306b,
0052 0x310d,
0053 0x3248,
0054 0x3382,
0055 0x34bd,
0056 0x35e7,
0057 0x3618,
0058 0x3794,
0059 0x3801,
0060 0x395d,
0061 0x3aae,
0062 0x3bff,
0063 0x07c9,
0064 };
0065
0066 static u16 poweroff[] = {
0067 0x07d9,
0068 };
0069
0070 struct tpohvga_plat_data {
0071 void (*plat_onoff)(int status);
0072 struct spi_device *spi;
0073 };
0074
0075 static void tpohvga_onoff(struct mmp_panel *panel, int status)
0076 {
0077 struct tpohvga_plat_data *plat = panel->plat_data;
0078 int ret;
0079
0080 if (status) {
0081 plat->plat_onoff(1);
0082
0083 ret = spi_write(plat->spi, init, sizeof(init));
0084 if (ret < 0)
0085 dev_warn(panel->dev, "init cmd failed(%d)\n", ret);
0086 } else {
0087 ret = spi_write(plat->spi, poweroff, sizeof(poweroff));
0088 if (ret < 0)
0089 dev_warn(panel->dev, "poweroff cmd failed(%d)\n", ret);
0090
0091 plat->plat_onoff(0);
0092 }
0093 }
0094
0095 static struct mmp_mode mmp_modes_tpohvga[] = {
0096 [0] = {
0097 .pixclock_freq = 10394400,
0098 .refresh = 60,
0099 .xres = 320,
0100 .yres = 480,
0101 .hsync_len = 10,
0102 .left_margin = 15,
0103 .right_margin = 10,
0104 .vsync_len = 2,
0105 .upper_margin = 4,
0106 .lower_margin = 2,
0107 .invert_pixclock = 1,
0108 .pix_fmt_out = PIXFMT_RGB565,
0109 },
0110 };
0111
0112 static int tpohvga_get_modelist(struct mmp_panel *panel,
0113 struct mmp_mode **modelist)
0114 {
0115 *modelist = mmp_modes_tpohvga;
0116 return 1;
0117 }
0118
0119 static struct mmp_panel panel_tpohvga = {
0120 .name = "tpohvga",
0121 .panel_type = PANELTYPE_ACTIVE,
0122 .get_modelist = tpohvga_get_modelist,
0123 .set_onoff = tpohvga_onoff,
0124 };
0125
0126 static int tpohvga_probe(struct spi_device *spi)
0127 {
0128 struct mmp_mach_panel_info *mi;
0129 int ret;
0130 struct tpohvga_plat_data *plat_data;
0131
0132
0133 mi = spi->dev.platform_data;
0134 if (mi == NULL) {
0135 dev_err(&spi->dev, "%s: no platform data defined\n", __func__);
0136 return -EINVAL;
0137 }
0138
0139
0140 spi->bits_per_word = 16;
0141 ret = spi_setup(spi);
0142 if (ret < 0) {
0143 dev_err(&spi->dev, "spi setup failed %d", ret);
0144 return ret;
0145 }
0146
0147 plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL);
0148 if (plat_data == NULL)
0149 return -ENOMEM;
0150
0151 plat_data->spi = spi;
0152 plat_data->plat_onoff = mi->plat_set_onoff;
0153 panel_tpohvga.plat_data = plat_data;
0154 panel_tpohvga.plat_path_name = mi->plat_path_name;
0155 panel_tpohvga.dev = &spi->dev;
0156
0157 mmp_register_panel(&panel_tpohvga);
0158
0159 return 0;
0160 }
0161
0162 static struct spi_driver panel_tpohvga_driver = {
0163 .driver = {
0164 .name = "tpo-hvga",
0165 },
0166 .probe = tpohvga_probe,
0167 };
0168 module_spi_driver(panel_tpohvga_driver);
0169
0170 MODULE_AUTHOR("Lisa Du<cldu@marvell.com>");
0171 MODULE_DESCRIPTION("Panel driver for tpohvga");
0172 MODULE_LICENSE("GPL");