515_display.patch 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
  2. index 1a9685eb8002..8bdb02aeaf0c 100644
  3. --- a/drivers/gpu/drm/panel/panel-simple.c
  4. +++ b/drivers/gpu/drm/panel/panel-simple.c
  5. @@ -4466,6 +4466,44 @@ static const struct panel_desc arm_rtsm = {
  6. .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
  7. };
  8. +static const struct drm_display_mode clockwork_cpi3_lcd_mode = {
  9. + .clock = 5800,
  10. + .hdisplay = 320,
  11. + .hsync_start = 320 + 6,
  12. + .hsync_end = 320 + 6 + 2,
  13. + .htotal = 320 + 6 + 2 + 60,
  14. + .vdisplay = 240,
  15. + .vsync_start = 240 + 2,
  16. + .vsync_end = 240 + 2 + 2,
  17. + .vtotal = 240 + 2 + 2 + 6,
  18. + .flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_PHSYNC,
  19. +};
  20. +
  21. +static const struct panel_desc clockwork_cpi3_lcd = {
  22. + .modes = &clockwork_cpi3_lcd_mode,
  23. + .num_modes = 1,
  24. + .bpc = 8,
  25. +};
  26. +
  27. +static const struct drm_display_mode clockwork_cpi3_hdmi_mode = {
  28. + .clock = 74250,
  29. + .hdisplay = 1280,
  30. + .hsync_start = 1280 + 110,
  31. + .hsync_end = 1280 + 110 + 40,
  32. + .htotal = 1280 + 110 + 40 + 220,
  33. + .vdisplay = 720,
  34. + .vsync_start = 720 + 5,
  35. + .vsync_end = 720 + 5 + 5,
  36. + .vtotal = 720 + 5 + 5 + 20,
  37. + .flags = DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_PHSYNC,
  38. +};
  39. +
  40. +static const struct panel_desc clockwork_cpi3_hdmi = {
  41. + .modes = &clockwork_cpi3_hdmi_mode,
  42. + .num_modes = 1,
  43. + .bpc = 8,
  44. +};
  45. +
  46. static const struct of_device_id platform_of_match[] = {
  47. {
  48. .compatible = "ampire,am-1280800n3tzqw-t00h",
  49. @@ -4906,6 +4944,12 @@ static const struct of_device_id platform_of_match[] = {
  50. /* Must be the last entry */
  51. .compatible = "panel-dpi",
  52. .data = &panel_dpi,
  53. + }, {
  54. + .compatible = "clockwork,cpi3-lcd",
  55. + .data = &clockwork_cpi3_lcd,
  56. + }, {
  57. + .compatible = "clockwork,cpi3-hdmi",
  58. + .data = &clockwork_cpi3_hdmi,
  59. }, {
  60. /* sentinel */
  61. }
  62. diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
  63. index e32694c13da5..9b606f172f80 100644
  64. --- a/drivers/video/backlight/Kconfig
  65. +++ b/drivers/video/backlight/Kconfig
  66. @@ -135,6 +135,12 @@ config LCD_OTM3225A
  67. If you have a panel based on the OTM3225A controller
  68. chip then say y to include a driver for it.
  69. +config LCD_KD027
  70. + tristate "STARTEK KD027 LCD Driver"
  71. + help
  72. + If you have a KD027 LCD panel, say Y to enable its LCD control
  73. + driver.
  74. +
  75. endif # LCD_CLASS_DEVICE
  76. #
  77. @@ -464,6 +470,12 @@ config BACKLIGHT_LED
  78. If you have a LCD backlight adjustable by LED class driver, say Y
  79. to enable this driver.
  80. +config BACKLIGHT_OCP8178
  81. + tristate "OCP8178 Backlight Driver"
  82. + depends on GPIOLIB
  83. + help
  84. + If you have an OCP8178, say Y to enable the backlight driver.
  85. +
  86. endif # BACKLIGHT_CLASS_DEVICE
  87. endmenu
  88. diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
  89. index cae2c83422ae..7eaf58dda80f 100644
  90. --- a/drivers/video/backlight/Makefile
  91. +++ b/drivers/video/backlight/Makefile
  92. @@ -17,6 +17,7 @@ obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
  93. obj-$(CONFIG_LCD_TDO24M) += tdo24m.o
  94. obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
  95. obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
  96. +obj-$(CONFIG_LCD_KD027) += kd027_lcd.o
  97. obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
  98. obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
  99. @@ -58,3 +59,4 @@ obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o
  100. obj-$(CONFIG_BACKLIGHT_ARCXCNN) += arcxcnn_bl.o
  101. obj-$(CONFIG_BACKLIGHT_RAVE_SP) += rave-sp-backlight.o
  102. obj-$(CONFIG_BACKLIGHT_LED) += led_bl.o
  103. +obj-$(CONFIG_BACKLIGHT_OCP8178) += ocp8178_bl.o
  104. diff --git a/drivers/video/backlight/kd027_lcd.c b/drivers/video/backlight/kd027_lcd.c
  105. new file mode 100644
  106. index 000000000000..24abec39d3bd
  107. --- /dev/null
  108. +++ b/drivers/video/backlight/kd027_lcd.c
  109. @@ -0,0 +1,250 @@
  110. +/*
  111. + * kd027_lcd.c
  112. + *
  113. + * This program is free software; you can redistribute it and/or modify
  114. + * it under the terms of the GNU General Public License as published by
  115. + * the Free Software Foundation; either version 2 of the License, or
  116. + * (at your option) any later version.
  117. + *
  118. + *
  119. + *
  120. + */
  121. +
  122. +#include <linux/gpio.h> /* Only for legacy support */
  123. +#include <linux/gpio/consumer.h>
  124. +#include <linux/init.h>
  125. +#include <linux/kernel.h>
  126. +#include <linux/module.h>
  127. +#include <linux/of.h>
  128. +#include <linux/of_gpio.h>
  129. +#include <linux/platform_data/gpio_backlight.h>
  130. +#include <linux/platform_device.h>
  131. +#include <linux/slab.h>
  132. +#include <linux/delay.h>
  133. +#include <linux/timer.h>
  134. +#include <linux/poll.h>
  135. +#include <linux/proc_fs.h>
  136. +#include <linux/seq_file.h>
  137. +#include <linux/sched.h>
  138. +#include <linux/interrupt.h>
  139. +#include <linux/irq.h>
  140. +#include <linux/io.h>
  141. +#include <linux/clk.h>
  142. +
  143. +struct kd027_lcd {
  144. + struct gpio_desc* rst_pin;
  145. + struct gpio_desc* cs_pin;
  146. + struct gpio_desc* sck_pin;
  147. + struct gpio_desc* sda_pin;
  148. + unsigned char init_seq[100];
  149. + unsigned char suspend_seq[20];
  150. + unsigned char resume_seq[20];
  151. + int init_seq_len;
  152. + int suspend_seq_len;
  153. + int resume_seq_len;
  154. +};
  155. +
  156. +struct kd027_lcd * lcd_data;
  157. +
  158. +static void kd027_write_lcd(unsigned char data)
  159. +{
  160. + unsigned char i;
  161. +
  162. + for(i = 0; i < 8; i++) {
  163. + if (data & 0x80)
  164. + gpiod_set_value(lcd_data->sda_pin, 1);
  165. + else
  166. + gpiod_set_value(lcd_data->sda_pin, 0);
  167. + gpiod_set_value(lcd_data->sck_pin, 0);
  168. + gpiod_set_value(lcd_data->sck_pin, 1);
  169. + data <<= 1;
  170. + }
  171. +}
  172. +
  173. +static void kd027_write_cmd_data(unsigned char c, unsigned char d)
  174. +{
  175. + gpiod_set_value(lcd_data->cs_pin, 0);
  176. + kd027_write_lcd(c);
  177. + kd027_write_lcd(d);
  178. + gpiod_set_value(lcd_data->cs_pin, 1);
  179. +}
  180. +
  181. +static void kd027_init(void)
  182. +{
  183. + int i;
  184. + for(i = 0; i < lcd_data->init_seq_len/2; i++) {
  185. + kd027_write_cmd_data(lcd_data->init_seq[i * 2], lcd_data->init_seq[i * 2 + 1]);
  186. + }
  187. +}
  188. +
  189. +#ifdef CONFIG_PROC_FS
  190. +static char global_buffer[64];
  191. +
  192. +static int kd027_proc_show(struct seq_file *m, void *v)
  193. +{
  194. + seq_printf(m, "kd027\n");
  195. + return 0;
  196. +}
  197. +
  198. +static int kd027_proc_open(struct inode *inode, struct file *file)
  199. +{
  200. + return single_open(file, kd027_proc_show, NULL);
  201. +}
  202. +
  203. +static ssize_t kd027_proc_read(struct file * file, char __user * buf, size_t size, loff_t * loff)
  204. +{
  205. + return 0;
  206. +}
  207. +
  208. +static ssize_t kd027_proc_write(struct file * file, const char __user * buf, size_t size, loff_t * loff)
  209. +{
  210. + int cmd, data;
  211. + char* tmp;
  212. +
  213. + if(copy_from_user(global_buffer, buf, size))
  214. + return -EFAULT;
  215. +
  216. + global_buffer[size] = 0;
  217. + cmd = simple_strtol(global_buffer, 0, 16);
  218. + tmp = strchr(global_buffer, ' ');
  219. + if(tmp) {
  220. + data = simple_strtol(tmp+1, 0, 16);
  221. + kd027_write_cmd_data(cmd, data);
  222. + }
  223. +
  224. + return size;
  225. +}
  226. +
  227. +static const struct proc_ops kd027_proc_fops = {
  228. + .proc_open = kd027_proc_open,
  229. + .proc_read = kd027_proc_read,
  230. + .proc_write = kd027_proc_write,
  231. + .proc_lseek = seq_lseek,
  232. + .proc_release = single_release,
  233. +};
  234. +
  235. +static int __init kd027_proc_init(void)
  236. +{
  237. + struct proc_dir_entry *r;
  238. +
  239. + r = proc_create("driver/lcd", S_IRWXUGO, NULL, &kd027_proc_fops);
  240. + if (!r)
  241. + return -ENOMEM;
  242. + return 0;
  243. +}
  244. +#else
  245. +static inline int kd027_proc_init(void) { return 0; }
  246. +#endif /* CONFIG_PROC_FS */
  247. +
  248. +static int kd027_probe(struct platform_device *pdev)
  249. +{
  250. + int ret;
  251. + struct device_node *np = pdev->dev.of_node;
  252. + struct device *dev = &pdev->dev;
  253. +
  254. + if ( !np) {
  255. + dev_err(&pdev->dev,
  256. + "failed to find platform data or device tree node.\n");
  257. + return -ENODEV;
  258. + }
  259. +
  260. + lcd_data = devm_kzalloc(&pdev->dev, sizeof(*lcd_data), GFP_KERNEL);
  261. + if (lcd_data == NULL)
  262. + return -ENOMEM;
  263. +
  264. + lcd_data->init_seq_len = of_property_read_variable_u8_array(np, "init-seq", lcd_data->init_seq, 1, 100);
  265. + lcd_data->suspend_seq_len = of_property_read_variable_u8_array(np, "suspend-seq", lcd_data->suspend_seq, 1, 20);
  266. + lcd_data->resume_seq_len = of_property_read_variable_u8_array(np, "resume-seq", lcd_data->resume_seq, 1, 20);
  267. +
  268. + lcd_data->rst_pin = devm_gpiod_get(dev, "lcd-rst", GPIOD_OUT_HIGH);
  269. + if (IS_ERR(lcd_data->rst_pin)) {
  270. + ret = PTR_ERR(lcd_data->rst_pin);
  271. +
  272. + if (ret != -EPROBE_DEFER) {
  273. + dev_err(dev,
  274. + "Error: The gpios parameter is missing or invalid.\n");
  275. + }
  276. + return ret;
  277. + }
  278. +
  279. + lcd_data->cs_pin = devm_gpiod_get(dev, "lcd-cs", GPIOD_OUT_HIGH);
  280. + if (IS_ERR(lcd_data->cs_pin)) {
  281. + ret = PTR_ERR(lcd_data->cs_pin);
  282. +
  283. + if (ret != -EPROBE_DEFER) {
  284. + dev_err(dev,
  285. + "Error: The gpios parameter is missing or invalid.\n");
  286. + }
  287. + return ret;
  288. + }
  289. +
  290. + lcd_data->sck_pin = devm_gpiod_get(dev, "lcd-sck", GPIOD_OUT_HIGH);
  291. + if (IS_ERR(lcd_data->sck_pin)) {
  292. + ret = PTR_ERR(lcd_data->sck_pin);
  293. +
  294. + if (ret != -EPROBE_DEFER) {
  295. + dev_err(dev,
  296. + "Error: The gpios parameter is missing or invalid.\n");
  297. + }
  298. + return ret;
  299. + }
  300. +
  301. + lcd_data->sda_pin = devm_gpiod_get(dev, "lcd-sda", GPIOD_OUT_HIGH);
  302. + if (IS_ERR(lcd_data->sda_pin)) {
  303. + ret = PTR_ERR(lcd_data->sda_pin);
  304. +
  305. + if (ret != -EPROBE_DEFER) {
  306. + dev_err(dev,
  307. + "Error: The gpios parameter is missing or invalid.\n");
  308. + }
  309. + return ret;
  310. + }
  311. +
  312. + kd027_init();
  313. + kd027_proc_init();
  314. +
  315. + return 0;
  316. +}
  317. +
  318. +static int kd027_suspend(struct platform_device * pdev, pm_message_t state)
  319. +{
  320. + int i;
  321. + for(i = 0; i < lcd_data->suspend_seq_len/2; i++) {
  322. + kd027_write_cmd_data(lcd_data->suspend_seq[i * 2], lcd_data->suspend_seq[i * 2 + 1]);
  323. + }
  324. + return 0;
  325. +}
  326. +
  327. +static int kd027_resume(struct platform_device * pdev)
  328. +{
  329. + int i;
  330. + for(i = 0; i < lcd_data->resume_seq_len/2; i++) {
  331. + kd027_write_cmd_data(lcd_data->resume_seq[i * 2], lcd_data->resume_seq[i * 2 + 1]);
  332. + }
  333. + return 0;
  334. +}
  335. +
  336. +#ifdef CONFIG_OF
  337. +static struct of_device_id kd027_of_match[] = {
  338. + { .compatible = "kd027-lcd" },
  339. + { /* sentinel */ }
  340. +};
  341. +
  342. +MODULE_DEVICE_TABLE(of, kd027_of_match);
  343. +#endif
  344. +
  345. +static struct platform_driver kd027_device_driver = {
  346. + .probe = kd027_probe,
  347. + .suspend = kd027_suspend,
  348. + .resume = kd027_resume,
  349. + .driver = {
  350. + .name = "kd027-lcd",
  351. + .of_match_table = of_match_ptr(kd027_of_match),
  352. + },
  353. +};
  354. +
  355. +module_platform_driver(kd027_device_driver);
  356. +
  357. +MODULE_LICENSE("GPL");
  358. +MODULE_DESCRIPTION("KD027 Driver");
  359. +
  360. diff --git a/drivers/video/backlight/ocp8178_bl.c b/drivers/video/backlight/ocp8178_bl.c
  361. new file mode 100644
  362. index 000000000000..0ffb9e513e50
  363. --- /dev/null
  364. +++ b/drivers/video/backlight/ocp8178_bl.c
  365. @@ -0,0 +1,349 @@
  366. +/*
  367. + * ocp8178_bl.c - ocp8178 backlight driver
  368. + *
  369. + * This program is free software; you can redistribute it and/or modify
  370. + * it under the terms of the GNU General Public License version 2 as
  371. + * published by the Free Software Foundation.
  372. + */
  373. +
  374. +#include <linux/backlight.h>
  375. +#include <linux/err.h>
  376. +#include <linux/fb.h>
  377. +#include <linux/gpio.h> /* Only for legacy support */
  378. +#include <linux/gpio/consumer.h>
  379. +#include <linux/init.h>
  380. +#include <linux/kernel.h>
  381. +#include <linux/module.h>
  382. +#include <linux/of.h>
  383. +#include <linux/of_gpio.h>
  384. +#include <linux/platform_data/gpio_backlight.h>
  385. +#include <linux/platform_device.h>
  386. +#include <linux/slab.h>
  387. +#include <linux/delay.h>
  388. +#include <linux/timer.h>
  389. +#include <linux/poll.h>
  390. +#include <linux/proc_fs.h>
  391. +#include <linux/seq_file.h>
  392. +#include <linux/sched.h>
  393. +#include <linux/interrupt.h>
  394. +#include <linux/irq.h>
  395. +#include <linux/io.h>
  396. +#include <linux/clk.h>
  397. +
  398. +struct ocp8178_backlight {
  399. + struct device *dev;
  400. + struct device *fbdev;
  401. +
  402. + struct gpio_desc *gpiod;
  403. + int def_value;
  404. + int current_value;
  405. +};
  406. +
  407. +#define DETECT_DELAY 200
  408. +#define DETECT_TIME 500
  409. +#define DETECT_WINDOW_TIME 1000
  410. +#define START_TIME 10
  411. +#define END_TIME 10
  412. +#define SHUTDOWN_TIME 3000
  413. +#define LOW_BIT_HIGH_TIME 10
  414. +#define LOW_BIT_LOW_TIME 50
  415. +#define HIGH_BIT_HIGH_TIME 50
  416. +#define HIGH_BIT_LOW_TIME 10
  417. +#define MAX_BRIGHTNESS_VALUE 9
  418. +
  419. +static void entry_1wire_mode(struct ocp8178_backlight *gbl)
  420. +{
  421. + unsigned long flags = 0;
  422. + local_irq_save(flags);
  423. + gpiod_set_value(gbl->gpiod, 0);
  424. + mdelay(SHUTDOWN_TIME/1000);
  425. + gpiod_set_value(gbl->gpiod, 1);
  426. + udelay(DETECT_DELAY);
  427. + gpiod_set_value(gbl->gpiod, 0);
  428. + udelay(DETECT_TIME);
  429. + gpiod_set_value(gbl->gpiod, 1);
  430. + udelay(DETECT_WINDOW_TIME);
  431. + local_irq_restore(flags);
  432. +}
  433. +
  434. +static inline void write_bit(struct ocp8178_backlight *gbl, int bit)
  435. +{
  436. + if (bit) {
  437. + gpiod_set_value(gbl->gpiod, 0);
  438. + udelay(HIGH_BIT_LOW_TIME);
  439. + gpiod_set_value(gbl->gpiod, 1);
  440. + udelay(HIGH_BIT_HIGH_TIME);
  441. + } else {
  442. + gpiod_set_value(gbl->gpiod, 0);
  443. + udelay(LOW_BIT_LOW_TIME);
  444. + gpiod_set_value(gbl->gpiod, 1);
  445. + udelay(LOW_BIT_HIGH_TIME);
  446. + }
  447. +}
  448. +
  449. +static void write_byte(struct ocp8178_backlight *gbl, int byte)
  450. +{
  451. + unsigned long flags = 0;
  452. + unsigned char data = 0x72;
  453. + int i;
  454. +
  455. + local_irq_save(flags);
  456. +
  457. + gpiod_set_value(gbl->gpiod, 1);
  458. + udelay(START_TIME);
  459. + for(i = 0; i < 8; i++) {
  460. + if(data & 0x80) {
  461. + write_bit(gbl, 1);
  462. + } else {
  463. + write_bit(gbl, 0);
  464. + }
  465. + data <<= 1;
  466. + }
  467. + gpiod_set_value(gbl->gpiod, 0);
  468. + udelay(END_TIME);
  469. +
  470. + data = byte & 0x1f;
  471. +
  472. + gpiod_set_value(gbl->gpiod, 1);
  473. + udelay(START_TIME);
  474. + for(i = 0; i < 8; i++) {
  475. + if(data & 0x80) {
  476. + write_bit(gbl, 1);
  477. + } else {
  478. + write_bit(gbl, 0);
  479. + }
  480. + data <<= 1;
  481. + }
  482. + gpiod_set_value(gbl->gpiod, 0);
  483. + udelay(END_TIME);
  484. + gpiod_set_value(gbl->gpiod, 1);
  485. +
  486. + local_irq_restore(flags);
  487. +}
  488. +
  489. +unsigned char ocp8178_bl_table[MAX_BRIGHTNESS_VALUE+1] = {0, 1, 4, 8, 12, 16, 20, 24, 28, 31};
  490. +
  491. +static int ocp8178_update_status(struct backlight_device *bl)
  492. +{
  493. + struct ocp8178_backlight *gbl = bl_get_data(bl);
  494. + int brightness = bl->props.brightness;
  495. +
  496. + if (bl->props.power != FB_BLANK_UNBLANK ||
  497. + bl->props.fb_blank != FB_BLANK_UNBLANK ||
  498. + bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
  499. + brightness = 0;
  500. +
  501. + if(brightness > MAX_BRIGHTNESS_VALUE) {
  502. + brightness = MAX_BRIGHTNESS_VALUE;
  503. + }
  504. +
  505. + write_byte(gbl, ocp8178_bl_table[brightness]);
  506. + gbl->current_value = brightness;
  507. +
  508. + return 0;
  509. +}
  510. +
  511. +static int ocp8178_get_brightness(struct backlight_device *bl)
  512. +{
  513. + struct ocp8178_backlight *gbl = bl_get_data(bl);
  514. + return gbl->current_value;
  515. +}
  516. +
  517. +static int ocp8178_check_fb(struct backlight_device *bl,
  518. + struct fb_info *info)
  519. +{
  520. + struct ocp8178_backlight *gbl = bl_get_data(bl);
  521. + return gbl->fbdev == NULL || gbl->fbdev == info->dev;
  522. +}
  523. +
  524. +static const struct backlight_ops ocp8178_backlight_ops = {
  525. + .options = BL_CORE_SUSPENDRESUME,
  526. + .update_status = ocp8178_update_status,
  527. + .get_brightness = ocp8178_get_brightness,
  528. + .check_fb = ocp8178_check_fb,
  529. +};
  530. +
  531. +static int ocp8178_probe_dt(struct platform_device *pdev,
  532. + struct ocp8178_backlight *gbl)
  533. +{
  534. + struct device *dev = &pdev->dev;
  535. + struct device_node *np = dev->of_node;
  536. + enum gpiod_flags flags;
  537. + int ret = 0;
  538. + u32 value32;
  539. +
  540. + of_property_read_u32(np, "default-brightness", &value32);
  541. + if(value32 > MAX_BRIGHTNESS_VALUE)
  542. + gbl->def_value = MAX_BRIGHTNESS_VALUE;
  543. + else
  544. + gbl->def_value = value32;
  545. + flags = gbl->def_value ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW;
  546. +
  547. + gbl->gpiod = devm_gpiod_get(dev, "backlight-control", flags);
  548. + if (IS_ERR(gbl->gpiod)) {
  549. + ret = PTR_ERR(gbl->gpiod);
  550. +
  551. + if (ret != -EPROBE_DEFER) {
  552. + dev_err(dev,
  553. + "Error: The gpios parameter is missing or invalid.\n");
  554. + }
  555. + }
  556. +
  557. + return ret;
  558. +}
  559. +
  560. +static struct backlight_device *backlight;
  561. +
  562. +#ifdef CONFIG_PROC_FS
  563. +static char global_buffer[64];
  564. +
  565. +static int ocp8178_proc_show(struct seq_file *m, void *v)
  566. +{
  567. + seq_printf(m, "ocp8178\n");
  568. + return 0;
  569. +}
  570. +
  571. +static int ocp8178_proc_open(struct inode *inode, struct file *file)
  572. +{
  573. + return single_open(file, ocp8178_proc_show, NULL);
  574. +}
  575. +
  576. +static int ocp8178_proc_read(struct file * file, char __user * buf, size_t size, loff_t * loff)
  577. +{
  578. + int value, len;
  579. + struct backlight_device *bl = backlight;
  580. + value = ocp8178_get_brightness(bl);
  581. + len = snprintf(global_buffer, sizeof(global_buffer), "%d\n", value);
  582. + return simple_read_from_buffer(buf, size, loff, global_buffer, len);
  583. +}
  584. +
  585. +static int ocp8178_proc_write(struct file * file, const char __user * buf, size_t size, loff_t * loff)
  586. +{
  587. + int data;
  588. + struct backlight_device *bl = backlight;
  589. +
  590. + if(copy_from_user(global_buffer, buf, size))
  591. + return -EFAULT;
  592. +
  593. + global_buffer[size] = 0;
  594. + if(global_buffer[0] == '+') {
  595. + bl->props.brightness = (bl->props.brightness + 1) % (MAX_BRIGHTNESS_VALUE + 1);
  596. + } else if(global_buffer[0] == '-') {
  597. + bl->props.brightness = (bl->props.brightness + MAX_BRIGHTNESS_VALUE) % (MAX_BRIGHTNESS_VALUE + 1);
  598. + } else {
  599. + data = simple_strtol(global_buffer, 0, 10);
  600. + if(data < 0) {
  601. + bl->props.brightness = 0;
  602. + } else if(data > MAX_BRIGHTNESS_VALUE) {
  603. + bl->props.brightness = MAX_BRIGHTNESS_VALUE;
  604. + } else {
  605. + bl->props.brightness = data;
  606. + }
  607. + }
  608. + backlight_update_status(bl);
  609. +
  610. + return size;
  611. +}
  612. +
  613. +static const struct proc_ops ocp8178_proc_fops = {
  614. + .proc_open = ocp8178_proc_open,
  615. + .proc_read = ocp8178_proc_read,
  616. + .proc_write = ocp8178_proc_write,
  617. + .proc_lseek = seq_lseek,
  618. + .proc_release = single_release,
  619. +};
  620. +
  621. +static int __init ocp8178_proc_init(void)
  622. +{
  623. + struct proc_dir_entry *r;
  624. +
  625. + r = proc_create("driver/backlight", S_IRWXUGO, NULL, &ocp8178_proc_fops);
  626. + if (!r)
  627. + return -ENOMEM;
  628. + return 0;
  629. +}
  630. +#else
  631. +static inline int ocp8178_proc_init(void) { return 0; }
  632. +#endif /* CONFIG_PROC_FS */
  633. +
  634. +static int ocp8178_probe(struct platform_device *pdev)
  635. +{
  636. + struct backlight_properties props;
  637. + struct backlight_device *bl;
  638. + struct ocp8178_backlight *gbl;
  639. + struct device_node *np = pdev->dev.of_node;
  640. + int ret;
  641. +
  642. + if ( !np) {
  643. + dev_err(&pdev->dev,
  644. + "failed to find platform data or device tree node.\n");
  645. + return -ENODEV;
  646. + }
  647. +
  648. + gbl = devm_kzalloc(&pdev->dev, sizeof(*gbl), GFP_KERNEL);
  649. + if (gbl == NULL)
  650. + return -ENOMEM;
  651. +
  652. + gbl->dev = &pdev->dev;
  653. +
  654. + ret = ocp8178_probe_dt(pdev, gbl);
  655. + if (ret)
  656. + return ret;
  657. +
  658. + gbl->current_value = gbl->def_value;
  659. +
  660. + memset(&props, 0, sizeof(props));
  661. + props.type = BACKLIGHT_RAW;
  662. + props.max_brightness = MAX_BRIGHTNESS_VALUE;
  663. + bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev),
  664. + &pdev->dev, gbl, &ocp8178_backlight_ops,
  665. + &props);
  666. + if (IS_ERR(bl)) {
  667. + dev_err(&pdev->dev, "failed to register backlight\n");
  668. + return PTR_ERR(bl);
  669. + }
  670. +
  671. + entry_1wire_mode(gbl);
  672. +
  673. + bl->props.brightness = gbl->def_value;
  674. + backlight_update_status(bl);
  675. +
  676. + platform_set_drvdata(pdev, bl);
  677. +
  678. + backlight = bl;
  679. + ocp8178_proc_init();
  680. +
  681. + return 0;
  682. +}
  683. +
  684. +static int ocp8178_suspend(struct platform_device *pdev, pm_message_t state)
  685. +{
  686. + return 0;
  687. +}
  688. +
  689. +static int ocp8178_resume(struct platform_device *pdev)
  690. +{
  691. + return 0;
  692. +}
  693. +
  694. +static struct of_device_id ocp8178_of_match[] = {
  695. + { .compatible = "ocp8178-backlight" },
  696. + { /* sentinel */ }
  697. +};
  698. +
  699. +MODULE_DEVICE_TABLE(of, ocp8178_of_match);
  700. +
  701. +static struct platform_driver ocp8178_driver = {
  702. + .driver = {
  703. + .name = "ocp8178-backlight",
  704. + .of_match_table = of_match_ptr(ocp8178_of_match),
  705. + },
  706. + .probe = ocp8178_probe,
  707. + .suspend = ocp8178_suspend,
  708. + .resume = ocp8178_resume,
  709. +};
  710. +
  711. +module_platform_driver(ocp8178_driver);
  712. +
  713. +MODULE_DESCRIPTION("OCP8178 Driver");
  714. +MODULE_LICENSE("GPL");
  715. diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
  716. index e035a63bbe5b..b2eb9cf314fb 100644
  717. --- a/drivers/video/fbdev/core/fbcon.c
  718. +++ b/drivers/video/fbdev/core/fbcon.c
  719. @@ -357,6 +357,7 @@ static int get_color(struct vc_data *vc, struct fb_info *info,
  720. static void fb_flashcursor(struct work_struct *work)
  721. {
  722. +#if 0
  723. struct fb_info *info = container_of(work, struct fb_info, queue);
  724. struct fbcon_ops *ops = info->fbcon_par;
  725. struct vc_data *vc = NULL;
  726. @@ -387,6 +388,7 @@ static void fb_flashcursor(struct work_struct *work)
  727. ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
  728. get_color(vc, info, c, 0));
  729. console_unlock();
  730. +#endif
  731. }
  732. static void cursor_timer_handler(struct timer_list *t)
  733. @@ -1319,6 +1321,7 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
  734. static void fbcon_cursor(struct vc_data *vc, int mode)
  735. {
  736. +#if 0
  737. struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
  738. struct fbcon_ops *ops = info->fbcon_par;
  739. int c = scr_readw((u16 *) vc->vc_pos);
  740. @@ -1340,6 +1343,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
  741. ops->cursor(vc, info, mode, get_color(vc, info, c, 1),
  742. get_color(vc, info, c, 0));
  743. +#endif
  744. }
  745. static int scrollback_phys_max = 0;
  746. diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
  747. index 528c87ff14d8..21ae9491051c 100644
  748. --- a/drivers/video/fbdev/core/fbmem.c
  749. +++ b/drivers/video/fbdev/core/fbmem.c
  750. @@ -524,6 +524,9 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
  751. image.width = logo->width;
  752. image.height = logo->height;
  753. + image.dx = (info->var.xres/2) - (logo->width/2);
  754. + image.dy = (info->var.yres/2) - (logo->height/2);
  755. + n = 1;
  756. if (rotate) {
  757. logo_rotate = kmalloc_array(logo->width, logo->height,