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 36 static 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 79 static u16 poweroff[] = { 80 0x07d9, 81 }; 82 83 struct tpohvga_plat_data { 84 void (*plat_onoff)(int status); 85 struct spi_device *spi; 86 }; 87 88 static 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 108 static 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 125 static int tpohvga_get_modelist(struct mmp_panel *panel, 126 struct mmp_mode **modelist) 127 { 128 *modelist = mmp_modes_tpohvga; 129 return 1; 130 } 131 132 static 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 139 static 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 175 static struct spi_driver panel_tpohvga_driver = { 176 .driver = { 177 .name = "tpo-hvga", 178 }, 179 .probe = tpohvga_probe, 180 }; 181 module_spi_driver(panel_tpohvga_driver); 182 183 MODULE_AUTHOR("Lisa Du<cldu@marvell.com>"); 184 MODULE_DESCRIPTION("Panel driver for tpohvga"); 185 MODULE_LICENSE("GPL"); 186