2 * Copyright (C) 2012 ROCKCHIP, Inc.
3 * drivers/video/display/transmitter/ssd2828.c
4 * author: hhb@rock-chips.com
5 * create date: 2013-01-17
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/delay.h>
17 #include <linux/rk_fb.h>
18 #include <mach/gpio.h>
19 #include <mach/iomux.h>
20 #include <mach/board.h>
21 #include <linux/rk_screen.h>
22 #include <linux/regulator/machine.h>
24 #include <linux/proc_fs.h>
25 #include <asm/uaccess.h>
26 #include <linux/slab.h>
30 #define TXD_PORT ssd2828->spi.mosi
31 #define CLK_PORT ssd2828->spi.sck
32 #define CS_PORT ssd2828->spi.cs
33 #define RXD_PORT ssd2828->spi.miso
35 #define CS_OUT() gpio_direction_output(CS_PORT, 0)
36 #define CS_SET() gpio_set_value(CS_PORT, GPIO_HIGH)
37 #define CS_CLR() gpio_set_value(CS_PORT, GPIO_LOW)
38 #define CLK_OUT() gpio_direction_output(CLK_PORT, 0)
39 #define CLK_SET() gpio_set_value(CLK_PORT, GPIO_HIGH)
40 #define CLK_CLR() gpio_set_value(CLK_PORT, GPIO_LOW)
41 #define TXD_OUT() gpio_direction_output(TXD_PORT, 0)
42 #define TXD_SET() gpio_set_value(TXD_PORT, GPIO_HIGH)
43 #define TXD_CLR() gpio_set_value(TXD_PORT, GPIO_LOW)
44 #define RXD_INPUT() gpio_direction_input(RXD_PORT)
45 #define RXD_GET() gpio_get_value(RXD_PORT)
48 struct ssd2828_t *ssd2828 = NULL;
49 void ssd_set_register(unsigned int reg_and_value);
51 int ssd2828_gpio_init(void *data) {
53 struct reset_t *reset = &ssd2828->reset;
54 struct power_t *vdd = &ssd2828->vddio;
55 struct spi_t *spi = &ssd2828->spi;
57 if(reset->reset_pin > INVALID_GPIO) {
58 ret = gpio_request(reset->reset_pin, "ssd2828_reset");
60 //gpio_free(reset->reset_pin);
61 printk("%s: request ssd2828_RST_PIN error\n", __func__);
65 rk30_mux_api_set(reset->mux_name, 0);
67 gpio_direction_output(reset->reset_pin, !reset->effect_value);
71 if(vdd->enable_pin > INVALID_GPIO) {
72 ret = gpio_request(vdd->enable_pin, "ssd2828_vddio");
74 //gpio_free(vdd->enable_pin);
75 printk("%s: request ssd2828_vddio_PIN error\n", __func__);
79 rk30_mux_api_set(vdd->mux_name, 0);
81 gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
85 vdd = &ssd2828->vdd_mipi;
86 if(vdd->enable_pin > INVALID_GPIO) {
87 ret = gpio_request(vdd->enable_pin, "ssd2828_vdd_mipi");
89 //gpio_free(vdd->enable_pin);
90 printk("%s: request ssd2828_vdd_mipi_PIN error\n", __func__);
94 rk30_mux_api_set(vdd->mux_name, 0);
96 gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
100 vdd = &ssd2828->shut;
101 if(vdd->enable_pin > INVALID_GPIO) {
102 ret = gpio_request(vdd->enable_pin, "ssd2828_shut");
104 //gpio_free(vdd->enable_pin);
105 printk("%s: request ssd2828_shut_PIN error\n", __func__);
109 rk30_mux_api_set(vdd->mux_name, 0);
111 gpio_direction_output(vdd->enable_pin, !vdd->effect_value);
115 if(spi->cs > INVALID_GPIO) {
116 ret = gpio_request(spi->cs, "ssd2828_spi_cs");
118 //gpio_free(spi->cs);
119 printk("%s: request ssd2828_spi->cs_PIN error\n", __func__);
123 rk30_mux_api_set(spi->cs_mux_name, 0);
125 gpio_direction_output(spi->cs, GPIO_HIGH);
128 if(spi->sck > INVALID_GPIO) {
129 ret = gpio_request(spi->sck, "ssd2828_spi_sck");
131 //gpio_free(spi->sck);
132 printk("%s: request ssd2828_spi->sck_PIN error\n", __func__);
135 if(spi->sck_mux_name)
136 rk30_mux_api_set(spi->sck_mux_name, 0);
138 gpio_direction_output(spi->sck, GPIO_HIGH);
141 if(spi->mosi > INVALID_GPIO) {
142 ret = gpio_request(spi->mosi, "ssd2828_spi_mosi");
144 //gpio_free(spi->mosi);
145 printk("%s: request ssd2828_spi->mosi_PIN error\n", __func__);
148 if(spi->mosi_mux_name)
149 rk30_mux_api_set(spi->mosi_mux_name, 0);
151 gpio_direction_output(spi->mosi, GPIO_HIGH);
154 if(spi->miso > INVALID_GPIO) {
155 ret = gpio_request(spi->miso, "ssd2828_spi_miso");
157 //gpio_free(spi->miso);
158 printk("%s: request ssd2828_spi->miso_PIN error\n", __func__);
161 if(spi->miso_mux_name)
162 rk30_mux_api_set(spi->miso_mux_name, 0);
164 gpio_direction_input(spi->miso);
172 int ssd2828_gpio_deinit(void *data) {
173 struct reset_t *reset = &ssd2828->reset;
174 struct power_t *vdd = &ssd2828->vddio;
175 struct spi_t *spi = &ssd2828->spi;
177 if(reset->reset_pin > INVALID_GPIO) {
178 gpio_direction_input(reset->reset_pin);
179 gpio_free(reset->reset_pin);
181 if(vdd->enable_pin > INVALID_GPIO) {
182 gpio_direction_input(vdd->enable_pin);
183 gpio_free(vdd->enable_pin);
185 vdd = &ssd2828->vdd_mipi;
186 if(vdd->enable_pin > INVALID_GPIO) {
187 gpio_direction_input(vdd->enable_pin);
188 gpio_free(vdd->enable_pin);
190 vdd = &ssd2828->shut;
191 if(vdd->enable_pin > INVALID_GPIO) {
192 gpio_direction_input(vdd->enable_pin);
193 gpio_free(vdd->enable_pin);
195 if(spi->cs > INVALID_GPIO) {
196 gpio_direction_input(spi->cs);
199 if(spi->sck > INVALID_GPIO) {
200 gpio_direction_input(spi->sck);
203 if(spi->mosi > INVALID_GPIO) {
204 gpio_direction_input(spi->mosi);
205 gpio_free(spi->mosi);
207 if(spi->miso > INVALID_GPIO) {
208 gpio_free(spi->miso);
213 int ssd2828_reset(void *data) {
215 struct reset_t *reset = &ssd2828->reset;
216 if(reset->reset_pin <= INVALID_GPIO)
218 gpio_set_value(reset->reset_pin, reset->effect_value);
219 if(reset->time_before_reset <= 0)
222 msleep(reset->time_before_reset);
224 gpio_set_value(reset->reset_pin, !reset->effect_value);
225 if(reset->time_after_reset <= 0)
228 msleep(reset->time_after_reset);
232 int ssd2828_vdd_enable(void *data) {
234 struct power_t *vdd = (struct power_t *)data;
235 if(vdd->enable_pin > INVALID_GPIO) {
236 gpio_set_value(vdd->enable_pin, vdd->effect_value);
237 } else if(vdd->name) {
238 struct regulator *ldo = regulator_get(NULL, vdd->name);
239 if (ldo == NULL || IS_ERR(ldo) ){
240 printk("%s: get %s ldo failed!\n", __func__, vdd->name);
244 regulator_set_voltage(ldo, vdd->voltage, vdd->voltage);
245 regulator_enable(ldo);
246 printk(" %s set %s=%dmV end\n", __func__, vdd->name, regulator_get_voltage(ldo));
252 int ssd2828_vdd_disable(void *data) {
254 struct power_t *vdd = (struct power_t *)data;
256 if(vdd->enable_pin > INVALID_GPIO) {
257 gpio_set_value(vdd->enable_pin, !vdd->effect_value);
258 } else if(vdd->name) {
259 struct regulator *ldo = regulator_get(NULL, vdd->name);
260 if (ldo == NULL || IS_ERR(ldo) ){
261 printk("%s: get %s ldo failed!\n", __func__, vdd->name);
265 while(regulator_is_enabled(ldo) > 0){
266 regulator_disable(ldo);
274 int ssd2828_power_up(void) {
277 struct ssd2828_t *ssd = (struct ssd2828_t *)ssd2828;
278 struct spi_t *spi = &ssd2828->spi;
279 ssd->vdd_mipi.enable(&ssd->vdd_mipi);
280 ssd->vddio.enable(&ssd->vddio);
281 ssd->reset.do_reset(&ssd->reset);
282 ssd->shut.enable(&ssd->shut);
284 gpio_direction_output(spi->cs, GPIO_HIGH);
285 gpio_direction_output(spi->sck, GPIO_LOW);
286 gpio_direction_input(spi->miso);
287 gpio_direction_output(spi->mosi, GPIO_LOW);
292 int ssd2828_power_down(void) {
295 struct ssd2828_t *ssd = (struct ssd2828_t *)ssd2828;
296 struct spi_t *spi = &ssd2828->spi;
298 ssd->shut.disable(&ssd->shut);
301 ssd_set_register(0x00b70300);
303 ssd_set_register(0x00b70304);
305 ssd_set_register(0x00b90000);
308 //set all gpio to low to avoid current leakage
309 gpio_direction_output(spi->cs, GPIO_LOW);
310 gpio_direction_output(spi->sck, GPIO_LOW);
311 gpio_direction_output(spi->miso, GPIO_LOW);
312 gpio_direction_output(spi->mosi, GPIO_LOW);
313 gpio_direction_output(ssd->reset.reset_pin, GPIO_LOW);
315 ssd->vddio.disable(&ssd->vddio);
316 ssd->vdd_mipi.disable(&ssd->vdd_mipi);
317 ssd->shut.enable(&ssd->shut);
324 /* spi write a data frame,type mean command or data
325 3 wire 24 bit SPI interface
328 static void spi_send_data(unsigned int data)
340 for (i = 0; i < 24; i++)
345 if (data & 0x00800000) {
360 static void spi_recv_data(unsigned int* data)
362 unsigned int i = 0, temp = 0x73; //read data
372 for(i = 0; i < 8; i++) // 8 bits Data
387 for(i = 0; i < 16; i++) // 16 bits Data
395 if(RXD_GET() == GPIO_HIGH)
405 #define DEVIE_ID (0x70 << 16)
406 void send_ctrl_cmd(unsigned int cmd)
408 unsigned int out = (DEVIE_ID | cmd );
412 static void send_data_cmd(unsigned int data)
414 unsigned int out = (DEVIE_ID | (0x2 << 16) | data );
418 unsigned int ssd_read_register(unsigned int reg) {
419 unsigned int data = 0;
421 spi_recv_data(&data);
425 void ssd_set_register(unsigned int reg_and_value)
427 send_ctrl_cmd(reg_and_value >> 16);
428 send_data_cmd(reg_and_value & 0x0000ffff);
431 int ssd_set_registers(unsigned int reg_array[], int n) {
434 for(i = 0; i < n; i++) {
435 if(reg_array[i] < 0x00b00000) { //the lowest address is 0xb0 of ssd2828
436 if(reg_array[i] < 20000)
437 udelay(reg_array[i]);
439 mdelay(reg_array[i]/1000);
442 ssd_set_register(reg_array[i]);
448 int ssd_mipi_dsi_send_dcs_packet(unsigned char regs[], int n) {
449 //unsigned int data = 0, i = 0;
450 ssd_set_register(0x00B70343); //
451 ssd_set_register(0x00B80000);
452 ssd_set_register(0x00Bc0001);
454 ssd_set_register(0x00Bf0000 | regs[0]);
456 ssd_set_register(0x00B7034b);
461 int _ssd2828_send_packet(unsigned char type, unsigned char regs[], int n) {
467 int ssd2828_send_packet(unsigned char type, unsigned char regs[], int n) {
468 return _ssd2828_send_packet(type, regs, n);
471 int ssd_mipi_dsi_read_dcs_packet(unsigned char *data, int n) {
475 i = ssd_read_register(0xc6);
476 printk("read mipi slave error:%04x\n", i);
477 ssd_set_register(0x00B70382);
478 ssd_set_register(0x00BB0008);
479 ssd_set_register(0x00C1000A);
480 ssd_set_register(0x00C00001);
481 ssd_set_register(0x00Bc0001);
482 ssd_set_register(0x00Bf0000 | *data);
484 i = ssd_read_register(0xc6);
485 printk("read mipi slave error:%04x\n", i);
488 i = ssd_read_register(0xff);
489 printk("read %02x:%04x\n", *data, i);
490 i = ssd_read_register(0xff);
491 printk("read %02x:%04x\n", *data, i);
492 i = ssd_read_register(0xff);
493 printk("read %02x:%04x\n", *data, i);
501 int ssd2828_get_id(void) {
505 id = ssd_read_register(0xb0);
510 static struct mipi_dsi_ops ssd2828_ops = {
513 .get_id = ssd2828_get_id,
514 .dsi_set_regs = ssd_set_registers,
515 .dsi_send_dcs_packet = ssd_mipi_dsi_send_dcs_packet,
516 .dsi_read_dcs_packet = ssd_mipi_dsi_read_dcs_packet,
517 .power_up = ssd2828_power_up,
518 .power_down = ssd2828_power_down,
522 static struct proc_dir_entry *reg_proc_entry;
524 int reg_proc_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
527 char *buf = kmalloc(count, GFP_KERNEL);
529 unsigned int regs_val = 0, read_val = 0;
530 ret = copy_from_user((void*)buf, buff, count);
533 data = strstr(data, "0x");
535 goto reg_proc_write_exit;
536 sscanf(data, "0x%x", ®s_val);
537 ssd_set_register(regs_val);
538 read_val = ssd_read_register(regs_val >> 16);
540 if(read_val != regs_val)
541 printk("%s fail:0x%04x\n", __func__, read_val);
551 int reg_proc_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
555 const char buf[32] = {0};
556 unsigned int regs_val = 0;
557 ret = copy_from_user((void*)buf, buff, count);
558 sscanf(buf, "0x%x", ®s_val);
559 regs_val = ssd_read_register(regs_val);
560 sprintf(buf, "0x%04x\n", regs_val);
561 copy_to_user(buff, buf, 4);
563 printk("%s:%04x\n", __func__, regs_val);
569 int reg_proc_open(struct inode *inode, struct file *file)
571 //printk("%s\n", __func__);
576 int reg_proc_close(struct inode *inode, struct file *file)
578 //printk("%s\n", __func__);
583 struct file_operations reg_proc_fops = {
584 .owner = THIS_MODULE,
585 .open = reg_proc_open,
586 .release = reg_proc_close,
587 .write = reg_proc_write,
588 .read = reg_proc_read,
591 static int reg_proc_init(char *name)
594 reg_proc_entry = create_proc_entry(name, 0666, NULL);
595 if(reg_proc_entry == NULL) {
596 printk("Couldn't create proc entry : %s!\n", name);
601 printk("Create proc entry:%s success!\n", name);
602 reg_proc_entry->proc_fops = ®_proc_fops;
609 static int ssd2828_probe(struct platform_device *pdev) {
611 if(pdev->dev.platform_data)
612 ssd2828 = pdev->dev.platform_data;
614 if(!ssd2828->gpio_init)
615 ssd2828->gpio_init = ssd2828_gpio_init;
617 if(!ssd2828->gpio_deinit)
618 ssd2828->gpio_deinit = ssd2828_gpio_deinit;
620 if(!ssd2828->power_up)
621 ssd2828->power_up = ssd2828_power_up;
622 if(!ssd2828->power_down)
623 ssd2828->power_down = ssd2828_power_down;
625 if(!ssd2828->reset.do_reset)
626 ssd2828->reset.do_reset = ssd2828_reset;
628 if(!ssd2828->vddio.enable)
629 ssd2828->vddio.enable = ssd2828_vdd_enable;
630 if(!ssd2828->vddio.disable)
631 ssd2828->vddio.disable = ssd2828_vdd_disable;
633 if(!ssd2828->vdd_mipi.enable)
634 ssd2828->vdd_mipi.enable = ssd2828_vdd_enable;
635 if(!ssd2828->vdd_mipi.disable)
636 ssd2828->vdd_mipi.disable = ssd2828_vdd_disable;
638 if(!ssd2828->shut.enable)
639 ssd2828->shut.enable = ssd2828_vdd_enable;
640 if(!ssd2828->shut.disable)
641 ssd2828->shut.disable = ssd2828_vdd_disable;
644 ssd2828_gpio_init(NULL);
645 reg_proc_init(ssd2828_ops.name);
650 static int ssd2828_remove(struct platform_device *pdev) {
653 ssd2828_gpio_deinit(NULL);
660 static struct platform_driver ssd2828_driver = {
661 .probe = ssd2828_probe,
662 .remove = ssd2828_remove,
663 //.suspend = mipi_dsi_suspend,
664 //.resume = mipi_dsi_resume,
667 .owner = THIS_MODULE,
671 static int __init ssd2828_init(void)
673 platform_driver_register(&ssd2828_driver);
676 register_dsi_ops(&ssd2828_ops);
678 ssd2828_ops.id = ssd2828->id;
682 static void __exit ssd2828_exit(void)
684 platform_driver_unregister(&ssd2828_driver);
685 del_dsi_ops(&ssd2828_ops);
688 subsys_initcall_sync(ssd2828_init);
689 module_exit(ssd2828_exit);