auo_k190x.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. /*
  2. * Common code for AUO-K190X framebuffer drivers
  3. *
  4. * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/kernel.h>
  12. #include <linux/gpio.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/pm_runtime.h>
  15. #include <linux/fb.h>
  16. #include <linux/delay.h>
  17. #include <linux/uaccess.h>
  18. #include <linux/vmalloc.h>
  19. #include <linux/regulator/consumer.h>
  20. #include <video/auo_k190xfb.h>
  21. #include "auo_k190x.h"
  22. struct panel_info {
  23. int w;
  24. int h;
  25. };
  26. /* table of panel specific parameters to be indexed into by the board drivers */
  27. static struct panel_info panel_table[] = {
  28. /* standard 6" */
  29. [AUOK190X_RESOLUTION_800_600] = {
  30. .w = 800,
  31. .h = 600,
  32. },
  33. /* standard 9" */
  34. [AUOK190X_RESOLUTION_1024_768] = {
  35. .w = 1024,
  36. .h = 768,
  37. },
  38. [AUOK190X_RESOLUTION_600_800] = {
  39. .w = 600,
  40. .h = 800,
  41. },
  42. [AUOK190X_RESOLUTION_768_1024] = {
  43. .w = 768,
  44. .h = 1024,
  45. },
  46. };
  47. /*
  48. * private I80 interface to the board driver
  49. */
  50. static void auok190x_issue_data(struct auok190xfb_par *par, u16 data)
  51. {
  52. par->board->set_ctl(par, AUOK190X_I80_WR, 0);
  53. par->board->set_hdb(par, data);
  54. par->board->set_ctl(par, AUOK190X_I80_WR, 1);
  55. }
  56. static void auok190x_issue_cmd(struct auok190xfb_par *par, u16 data)
  57. {
  58. par->board->set_ctl(par, AUOK190X_I80_DC, 0);
  59. auok190x_issue_data(par, data);
  60. par->board->set_ctl(par, AUOK190X_I80_DC, 1);
  61. }
  62. /**
  63. * Conversion of 16bit color to 4bit grayscale
  64. * does roughly (0.3 * R + 0.6 G + 0.1 B) / 2
  65. */
  66. static inline int rgb565_to_gray4(u16 data, struct fb_var_screeninfo *var)
  67. {
  68. return ((((data & 0xF800) >> var->red.offset) * 77 +
  69. ((data & 0x07E0) >> (var->green.offset + 1)) * 151 +
  70. ((data & 0x1F) >> var->blue.offset) * 28) >> 8 >> 1);
  71. }
  72. static int auok190x_issue_pixels_rgb565(struct auok190xfb_par *par, int size,
  73. u16 *data)
  74. {
  75. struct fb_var_screeninfo *var = &par->info->var;
  76. struct device *dev = par->info->device;
  77. int i;
  78. u16 tmp;
  79. if (size & 7) {
  80. dev_err(dev, "issue_pixels: size %d must be a multiple of 8\n",
  81. size);
  82. return -EINVAL;
  83. }
  84. for (i = 0; i < (size >> 2); i++) {
  85. par->board->set_ctl(par, AUOK190X_I80_WR, 0);
  86. tmp = (rgb565_to_gray4(data[4*i], var) & 0x000F);
  87. tmp |= (rgb565_to_gray4(data[4*i+1], var) << 4) & 0x00F0;
  88. tmp |= (rgb565_to_gray4(data[4*i+2], var) << 8) & 0x0F00;
  89. tmp |= (rgb565_to_gray4(data[4*i+3], var) << 12) & 0xF000;
  90. par->board->set_hdb(par, tmp);
  91. par->board->set_ctl(par, AUOK190X_I80_WR, 1);
  92. }
  93. return 0;
  94. }
  95. static int auok190x_issue_pixels_gray8(struct auok190xfb_par *par, int size,
  96. u16 *data)
  97. {
  98. struct device *dev = par->info->device;
  99. int i;
  100. u16 tmp;
  101. if (size & 3) {
  102. dev_err(dev, "issue_pixels: size %d must be a multiple of 4\n",
  103. size);
  104. return -EINVAL;
  105. }
  106. for (i = 0; i < (size >> 1); i++) {
  107. par->board->set_ctl(par, AUOK190X_I80_WR, 0);
  108. /* simple reduction of 8bit staticgray to 4bit gray
  109. * combines 4 * 4bit pixel values into a 16bit value
  110. */
  111. tmp = (data[2*i] & 0xF0) >> 4;
  112. tmp |= (data[2*i] & 0xF000) >> 8;
  113. tmp |= (data[2*i+1] & 0xF0) << 4;
  114. tmp |= (data[2*i+1] & 0xF000);
  115. par->board->set_hdb(par, tmp);
  116. par->board->set_ctl(par, AUOK190X_I80_WR, 1);
  117. }
  118. return 0;
  119. }
  120. static int auok190x_issue_pixels(struct auok190xfb_par *par, int size,
  121. u16 *data)
  122. {
  123. struct fb_info *info = par->info;
  124. struct device *dev = par->info->device;
  125. if (info->var.bits_per_pixel == 8 && info->var.grayscale)
  126. auok190x_issue_pixels_gray8(par, size, data);
  127. else if (info->var.bits_per_pixel == 16)
  128. auok190x_issue_pixels_rgb565(par, size, data);
  129. else
  130. dev_err(dev, "unsupported color mode (bits: %d, gray: %d)\n",
  131. info->var.bits_per_pixel, info->var.grayscale);
  132. return 0;
  133. }
  134. static u16 auok190x_read_data(struct auok190xfb_par *par)
  135. {
  136. u16 data;
  137. par->board->set_ctl(par, AUOK190X_I80_OE, 0);
  138. data = par->board->get_hdb(par);
  139. par->board->set_ctl(par, AUOK190X_I80_OE, 1);
  140. return data;
  141. }
  142. /*
  143. * Command interface for the controller drivers
  144. */
  145. void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data)
  146. {
  147. par->board->set_ctl(par, AUOK190X_I80_CS, 0);
  148. auok190x_issue_cmd(par, data);
  149. par->board->set_ctl(par, AUOK190X_I80_CS, 1);
  150. }
  151. EXPORT_SYMBOL_GPL(auok190x_send_command_nowait);
  152. void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd,
  153. int argc, u16 *argv)
  154. {
  155. int i;
  156. par->board->set_ctl(par, AUOK190X_I80_CS, 0);
  157. auok190x_issue_cmd(par, cmd);
  158. for (i = 0; i < argc; i++)
  159. auok190x_issue_data(par, argv[i]);
  160. par->board->set_ctl(par, AUOK190X_I80_CS, 1);
  161. }
  162. EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_nowait);
  163. int auok190x_send_command(struct auok190xfb_par *par, u16 data)
  164. {
  165. int ret;
  166. ret = par->board->wait_for_rdy(par);
  167. if (ret)
  168. return ret;
  169. auok190x_send_command_nowait(par, data);
  170. return 0;
  171. }
  172. EXPORT_SYMBOL_GPL(auok190x_send_command);
  173. int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd,
  174. int argc, u16 *argv)
  175. {
  176. int ret;
  177. ret = par->board->wait_for_rdy(par);
  178. if (ret)
  179. return ret;
  180. auok190x_send_cmdargs_nowait(par, cmd, argc, argv);
  181. return 0;
  182. }
  183. EXPORT_SYMBOL_GPL(auok190x_send_cmdargs);
  184. int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd,
  185. int argc, u16 *argv)
  186. {
  187. int i, ret;
  188. ret = par->board->wait_for_rdy(par);
  189. if (ret)
  190. return ret;
  191. par->board->set_ctl(par, AUOK190X_I80_CS, 0);
  192. auok190x_issue_cmd(par, cmd);
  193. for (i = 0; i < argc; i++)
  194. argv[i] = auok190x_read_data(par);
  195. par->board->set_ctl(par, AUOK190X_I80_CS, 1);
  196. return 0;
  197. }
  198. EXPORT_SYMBOL_GPL(auok190x_read_cmdargs);
  199. void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par, u16 cmd,
  200. int argc, u16 *argv, int size, u16 *data)
  201. {
  202. int i;
  203. par->board->set_ctl(par, AUOK190X_I80_CS, 0);
  204. auok190x_issue_cmd(par, cmd);
  205. for (i = 0; i < argc; i++)
  206. auok190x_issue_data(par, argv[i]);
  207. auok190x_issue_pixels(par, size, data);
  208. par->board->set_ctl(par, AUOK190X_I80_CS, 1);
  209. }
  210. EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels_nowait);
  211. int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd,
  212. int argc, u16 *argv, int size, u16 *data)
  213. {
  214. int ret;
  215. ret = par->board->wait_for_rdy(par);
  216. if (ret)
  217. return ret;
  218. auok190x_send_cmdargs_pixels_nowait(par, cmd, argc, argv, size, data);
  219. return 0;
  220. }
  221. EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels);
  222. /*
  223. * fbdefio callbacks - common on both controllers.
  224. */
  225. static void auok190xfb_dpy_first_io(struct fb_info *info)
  226. {
  227. /* tell runtime-pm that we wish to use the device in a short time */
  228. pm_runtime_get(info->device);
  229. }
  230. /* this is called back from the deferred io workqueue */
  231. static void auok190xfb_dpy_deferred_io(struct fb_info *info,
  232. struct list_head *pagelist)
  233. {
  234. struct fb_deferred_io *fbdefio = info->fbdefio;
  235. struct auok190xfb_par *par = info->par;
  236. u16 line_length = info->fix.line_length;
  237. u16 yres = info->var.yres;
  238. u16 y1 = 0, h = 0;
  239. int prev_index = -1;
  240. struct page *cur;
  241. int h_inc;
  242. int threshold;
  243. if (!list_empty(pagelist))
  244. /* the device resume should've been requested through first_io,
  245. * if the resume did not finish until now, wait for it.
  246. */
  247. pm_runtime_barrier(info->device);
  248. else
  249. /* We reached this via the fsync or some other way.
  250. * In either case the first_io function did not run,
  251. * so we runtime_resume the device here synchronously.
  252. */
  253. pm_runtime_get_sync(info->device);
  254. /* Do a full screen update every n updates to prevent
  255. * excessive darkening of the Sipix display.
  256. * If we do this, there is no need to walk the pages.
  257. */
  258. if (par->need_refresh(par)) {
  259. par->update_all(par);
  260. goto out;
  261. }
  262. /* height increment is fixed per page */
  263. h_inc = DIV_ROUND_UP(PAGE_SIZE , line_length);
  264. /* calculate number of pages from pixel height */
  265. threshold = par->consecutive_threshold / h_inc;
  266. if (threshold < 1)
  267. threshold = 1;
  268. /* walk the written page list and swizzle the data */
  269. list_for_each_entry(cur, &fbdefio->pagelist, lru) {
  270. if (prev_index < 0) {
  271. /* just starting so assign first page */
  272. y1 = (cur->index << PAGE_SHIFT) / line_length;
  273. h = h_inc;
  274. } else if ((cur->index - prev_index) <= threshold) {
  275. /* page is within our threshold for single updates */
  276. h += h_inc * (cur->index - prev_index);
  277. } else {
  278. /* page not consecutive, issue previous update first */
  279. par->update_partial(par, y1, y1 + h);
  280. /* start over with our non consecutive page */
  281. y1 = (cur->index << PAGE_SHIFT) / line_length;
  282. h = h_inc;
  283. }
  284. prev_index = cur->index;
  285. }
  286. /* if we still have any pages to update we do so now */
  287. if (h >= yres)
  288. /* its a full screen update, just do it */
  289. par->update_all(par);
  290. else
  291. par->update_partial(par, y1, min((u16) (y1 + h), yres));
  292. out:
  293. pm_runtime_mark_last_busy(info->device);
  294. pm_runtime_put_autosuspend(info->device);
  295. }
  296. /*
  297. * framebuffer operations
  298. */
  299. /*
  300. * this is the slow path from userspace. they can seek and write to
  301. * the fb. it's inefficient to do anything less than a full screen draw
  302. */
  303. static ssize_t auok190xfb_write(struct fb_info *info, const char __user *buf,
  304. size_t count, loff_t *ppos)
  305. {
  306. struct auok190xfb_par *par = info->par;
  307. unsigned long p = *ppos;
  308. void *dst;
  309. int err = 0;
  310. unsigned long total_size;
  311. if (info->state != FBINFO_STATE_RUNNING)
  312. return -EPERM;
  313. total_size = info->fix.smem_len;
  314. if (p > total_size)
  315. return -EFBIG;
  316. if (count > total_size) {
  317. err = -EFBIG;
  318. count = total_size;
  319. }
  320. if (count + p > total_size) {
  321. if (!err)
  322. err = -ENOSPC;
  323. count = total_size - p;
  324. }
  325. dst = (void *)(info->screen_base + p);
  326. if (copy_from_user(dst, buf, count))
  327. err = -EFAULT;
  328. if (!err)
  329. *ppos += count;
  330. par->update_all(par);
  331. return (err) ? err : count;
  332. }
  333. static void auok190xfb_fillrect(struct fb_info *info,
  334. const struct fb_fillrect *rect)
  335. {
  336. struct auok190xfb_par *par = info->par;
  337. sys_fillrect(info, rect);
  338. par->update_all(par);
  339. }
  340. static void auok190xfb_copyarea(struct fb_info *info,
  341. const struct fb_copyarea *area)
  342. {
  343. struct auok190xfb_par *par = info->par;
  344. sys_copyarea(info, area);
  345. par->update_all(par);
  346. }
  347. static void auok190xfb_imageblit(struct fb_info *info,
  348. const struct fb_image *image)
  349. {
  350. struct auok190xfb_par *par = info->par;
  351. sys_imageblit(info, image);
  352. par->update_all(par);
  353. }
  354. static int auok190xfb_check_var(struct fb_var_screeninfo *var,
  355. struct fb_info *info)
  356. {
  357. struct device *dev = info->device;
  358. struct auok190xfb_par *par = info->par;
  359. struct panel_info *panel = &panel_table[par->resolution];
  360. int size;
  361. /*
  362. * Color depth
  363. */
  364. if (var->bits_per_pixel == 8 && var->grayscale == 1) {
  365. /*
  366. * For 8-bit grayscale, R, G, and B offset are equal.
  367. */
  368. var->red.length = 8;
  369. var->red.offset = 0;
  370. var->red.msb_right = 0;
  371. var->green.length = 8;
  372. var->green.offset = 0;
  373. var->green.msb_right = 0;
  374. var->blue.length = 8;
  375. var->blue.offset = 0;
  376. var->blue.msb_right = 0;
  377. var->transp.length = 0;
  378. var->transp.offset = 0;
  379. var->transp.msb_right = 0;
  380. } else if (var->bits_per_pixel == 16) {
  381. var->red.length = 5;
  382. var->red.offset = 11;
  383. var->red.msb_right = 0;
  384. var->green.length = 6;
  385. var->green.offset = 5;
  386. var->green.msb_right = 0;
  387. var->blue.length = 5;
  388. var->blue.offset = 0;
  389. var->blue.msb_right = 0;
  390. var->transp.length = 0;
  391. var->transp.offset = 0;
  392. var->transp.msb_right = 0;
  393. } else {
  394. dev_warn(dev, "unsupported color mode (bits: %d, grayscale: %d)\n",
  395. info->var.bits_per_pixel, info->var.grayscale);
  396. return -EINVAL;
  397. }
  398. /*
  399. * Dimensions
  400. */
  401. switch (var->rotate) {
  402. case FB_ROTATE_UR:
  403. case FB_ROTATE_UD:
  404. var->xres = panel->w;
  405. var->yres = panel->h;
  406. break;
  407. case FB_ROTATE_CW:
  408. case FB_ROTATE_CCW:
  409. var->xres = panel->h;
  410. var->yres = panel->w;
  411. break;
  412. default:
  413. dev_dbg(dev, "Invalid rotation request\n");
  414. return -EINVAL;
  415. }
  416. var->xres_virtual = var->xres;
  417. var->yres_virtual = var->yres;
  418. /*
  419. * Memory limit
  420. */
  421. size = var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8;
  422. if (size > info->fix.smem_len) {
  423. dev_err(dev, "Memory limit exceeded, requested %dK\n",
  424. size >> 10);
  425. return -ENOMEM;
  426. }
  427. return 0;
  428. }
  429. static int auok190xfb_set_fix(struct fb_info *info)
  430. {
  431. struct fb_fix_screeninfo *fix = &info->fix;
  432. struct fb_var_screeninfo *var = &info->var;
  433. fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
  434. fix->type = FB_TYPE_PACKED_PIXELS;
  435. fix->accel = FB_ACCEL_NONE;
  436. fix->visual = (var->grayscale) ? FB_VISUAL_STATIC_PSEUDOCOLOR
  437. : FB_VISUAL_TRUECOLOR;
  438. fix->xpanstep = 0;
  439. fix->ypanstep = 0;
  440. fix->ywrapstep = 0;
  441. return 0;
  442. }
  443. static int auok190xfb_set_par(struct fb_info *info)
  444. {
  445. struct auok190xfb_par *par = info->par;
  446. par->rotation = info->var.rotate;
  447. auok190xfb_set_fix(info);
  448. /* reinit the controller to honor the rotation */
  449. par->init(par);
  450. /* wait for init to complete */
  451. par->board->wait_for_rdy(par);
  452. return 0;
  453. }
  454. static struct fb_ops auok190xfb_ops = {
  455. .owner = THIS_MODULE,
  456. .fb_read = fb_sys_read,
  457. .fb_write = auok190xfb_write,
  458. .fb_fillrect = auok190xfb_fillrect,
  459. .fb_copyarea = auok190xfb_copyarea,
  460. .fb_imageblit = auok190xfb_imageblit,
  461. .fb_check_var = auok190xfb_check_var,
  462. .fb_set_par = auok190xfb_set_par,
  463. };
  464. /*
  465. * Controller-functions common to both K1900 and K1901
  466. */
  467. static int auok190x_read_temperature(struct auok190xfb_par *par)
  468. {
  469. struct device *dev = par->info->device;
  470. u16 data[4];
  471. int temp;
  472. pm_runtime_get_sync(dev);
  473. mutex_lock(&(par->io_lock));
  474. auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data);
  475. mutex_unlock(&(par->io_lock));
  476. pm_runtime_mark_last_busy(dev);
  477. pm_runtime_put_autosuspend(dev);
  478. /* sanitize and split of half-degrees for now */
  479. temp = ((data[0] & AUOK190X_VERSION_TEMP_MASK) >> 1);
  480. /* handle positive and negative temperatures */
  481. if (temp >= 201)
  482. return (255 - temp + 1) * (-1);
  483. else
  484. return temp;
  485. }
  486. static void auok190x_identify(struct auok190xfb_par *par)
  487. {
  488. struct device *dev = par->info->device;
  489. u16 data[4];
  490. pm_runtime_get_sync(dev);
  491. mutex_lock(&(par->io_lock));
  492. auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data);
  493. mutex_unlock(&(par->io_lock));
  494. par->epd_type = data[1] & AUOK190X_VERSION_TEMP_MASK;
  495. par->panel_size_int = AUOK190X_VERSION_SIZE_INT(data[2]);
  496. par->panel_size_float = AUOK190X_VERSION_SIZE_FLOAT(data[2]);
  497. par->panel_model = AUOK190X_VERSION_MODEL(data[2]);
  498. par->tcon_version = AUOK190X_VERSION_TCON(data[3]);
  499. par->lut_version = AUOK190X_VERSION_LUT(data[3]);
  500. dev_dbg(dev, "panel %d.%din, model 0x%x, EPD 0x%x TCON-rev 0x%x, LUT-rev 0x%x",
  501. par->panel_size_int, par->panel_size_float, par->panel_model,
  502. par->epd_type, par->tcon_version, par->lut_version);
  503. pm_runtime_mark_last_busy(dev);
  504. pm_runtime_put_autosuspend(dev);
  505. }
  506. /*
  507. * Sysfs functions
  508. */
  509. static ssize_t update_mode_show(struct device *dev,
  510. struct device_attribute *attr, char *buf)
  511. {
  512. struct fb_info *info = dev_get_drvdata(dev);
  513. struct auok190xfb_par *par = info->par;
  514. return sprintf(buf, "%d\n", par->update_mode);
  515. }
  516. static ssize_t update_mode_store(struct device *dev,
  517. struct device_attribute *attr,
  518. const char *buf, size_t count)
  519. {
  520. struct fb_info *info = dev_get_drvdata(dev);
  521. struct auok190xfb_par *par = info->par;
  522. int mode, ret;
  523. ret = kstrtoint(buf, 10, &mode);
  524. if (ret)
  525. return ret;
  526. par->update_mode = mode;
  527. /* if we enter a better mode, do a full update */
  528. if (par->last_mode > 1 && mode < par->last_mode)
  529. par->update_all(par);
  530. return count;
  531. }
  532. static ssize_t flash_show(struct device *dev, struct device_attribute *attr,
  533. char *buf)
  534. {
  535. struct fb_info *info = dev_get_drvdata(dev);
  536. struct auok190xfb_par *par = info->par;
  537. return sprintf(buf, "%d\n", par->flash);
  538. }
  539. static ssize_t flash_store(struct device *dev, struct device_attribute *attr,
  540. const char *buf, size_t count)
  541. {
  542. struct fb_info *info = dev_get_drvdata(dev);
  543. struct auok190xfb_par *par = info->par;
  544. int flash, ret;
  545. ret = kstrtoint(buf, 10, &flash);
  546. if (ret)
  547. return ret;
  548. if (flash > 0)
  549. par->flash = 1;
  550. else
  551. par->flash = 0;
  552. return count;
  553. }
  554. static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
  555. char *buf)
  556. {
  557. struct fb_info *info = dev_get_drvdata(dev);
  558. struct auok190xfb_par *par = info->par;
  559. int temp;
  560. temp = auok190x_read_temperature(par);
  561. return sprintf(buf, "%d\n", temp);
  562. }
  563. static DEVICE_ATTR(update_mode, 0644, update_mode_show, update_mode_store);
  564. static DEVICE_ATTR(flash, 0644, flash_show, flash_store);
  565. static DEVICE_ATTR(temp, 0644, temp_show, NULL);
  566. static struct attribute *auok190x_attributes[] = {
  567. &dev_attr_update_mode.attr,
  568. &dev_attr_flash.attr,
  569. &dev_attr_temp.attr,
  570. NULL
  571. };
  572. static const struct attribute_group auok190x_attr_group = {
  573. .attrs = auok190x_attributes,
  574. };
  575. static int auok190x_power(struct auok190xfb_par *par, bool on)
  576. {
  577. struct auok190x_board *board = par->board;
  578. int ret;
  579. if (on) {
  580. /* We should maintain POWER up for at least 80ms before set
  581. * RST_N and SLP_N to high (TCON spec 20100803_v35 p59)
  582. */
  583. ret = regulator_enable(par->regulator);
  584. if (ret)
  585. return ret;
  586. msleep(200);
  587. gpio_set_value(board->gpio_nrst, 1);
  588. gpio_set_value(board->gpio_nsleep, 1);
  589. msleep(200);
  590. } else {
  591. regulator_disable(par->regulator);
  592. gpio_set_value(board->gpio_nrst, 0);
  593. gpio_set_value(board->gpio_nsleep, 0);
  594. }
  595. return 0;
  596. }
  597. /*
  598. * Recovery - powercycle the controller
  599. */
  600. static void auok190x_recover(struct auok190xfb_par *par)
  601. {
  602. struct device *dev = par->info->device;
  603. auok190x_power(par, 0);
  604. msleep(100);
  605. auok190x_power(par, 1);
  606. /* after powercycling the device, it's always active */
  607. pm_runtime_set_active(dev);
  608. par->standby = 0;
  609. par->init(par);
  610. /* wait for init to complete */
  611. par->board->wait_for_rdy(par);
  612. }
  613. /*
  614. * Power-management
  615. */
  616. #ifdef CONFIG_PM
  617. static int auok190x_runtime_suspend(struct device *dev)
  618. {
  619. struct platform_device *pdev = to_platform_device(dev);
  620. struct fb_info *info = platform_get_drvdata(pdev);
  621. struct auok190xfb_par *par = info->par;
  622. struct auok190x_board *board = par->board;
  623. u16 standby_param;
  624. /* take and keep the lock until we are resumed, as the controller
  625. * will never reach the non-busy state when in standby mode
  626. */
  627. mutex_lock(&(par->io_lock));
  628. if (par->standby) {
  629. dev_warn(dev, "already in standby, runtime-pm pairing mismatch\n");
  630. mutex_unlock(&(par->io_lock));
  631. return 0;
  632. }
  633. /* according to runtime_pm.txt runtime_suspend only means, that the
  634. * device will not process data and will not communicate with the CPU
  635. * As we hold the lock, this stays true even without standby
  636. */
  637. if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
  638. dev_dbg(dev, "runtime suspend without standby\n");
  639. goto finish;
  640. } else if (board->quirks & AUOK190X_QUIRK_STANDBYPARAM) {
  641. /* for some TCON versions STANDBY expects a parameter (0) but
  642. * it seems the real tcon version has to be determined yet.
  643. */
  644. dev_dbg(dev, "runtime suspend with additional empty param\n");
  645. standby_param = 0;
  646. auok190x_send_cmdargs(par, AUOK190X_CMD_STANDBY, 1,
  647. &standby_param);
  648. } else {
  649. dev_dbg(dev, "runtime suspend without param\n");
  650. auok190x_send_command(par, AUOK190X_CMD_STANDBY);
  651. }
  652. msleep(64);
  653. finish:
  654. par->standby = 1;
  655. return 0;
  656. }
  657. static int auok190x_runtime_resume(struct device *dev)
  658. {
  659. struct platform_device *pdev = to_platform_device(dev);
  660. struct fb_info *info = platform_get_drvdata(pdev);
  661. struct auok190xfb_par *par = info->par;
  662. struct auok190x_board *board = par->board;
  663. if (!par->standby) {
  664. dev_warn(dev, "not in standby, runtime-pm pairing mismatch\n");
  665. return 0;
  666. }
  667. if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
  668. dev_dbg(dev, "runtime resume without standby\n");
  669. } else {
  670. /* when in standby, controller is always busy
  671. * and only accepts the wakeup command
  672. */
  673. dev_dbg(dev, "runtime resume from standby\n");
  674. auok190x_send_command_nowait(par, AUOK190X_CMD_WAKEUP);
  675. msleep(160);
  676. /* wait for the controller to be ready and release the lock */
  677. board->wait_for_rdy(par);
  678. }
  679. par->standby = 0;
  680. mutex_unlock(&(par->io_lock));
  681. return 0;
  682. }
  683. static int auok190x_suspend(struct device *dev)
  684. {
  685. struct platform_device *pdev = to_platform_device(dev);
  686. struct fb_info *info = platform_get_drvdata(pdev);
  687. struct auok190xfb_par *par = info->par;
  688. struct auok190x_board *board = par->board;
  689. int ret;
  690. dev_dbg(dev, "suspend\n");
  691. if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
  692. /* suspend via powering off the ic */
  693. dev_dbg(dev, "suspend with broken standby\n");
  694. auok190x_power(par, 0);
  695. } else {
  696. dev_dbg(dev, "suspend using sleep\n");
  697. /* the sleep state can only be entered from the standby state.
  698. * pm_runtime_get_noresume gets called before the suspend call.
  699. * So the devices usage count is >0 but it is not necessarily
  700. * active.
  701. */
  702. if (!pm_runtime_status_suspended(dev)) {
  703. ret = auok190x_runtime_suspend(dev);
  704. if (ret < 0) {
  705. dev_err(dev, "auok190x_runtime_suspend failed with %d\n",
  706. ret);
  707. return ret;
  708. }
  709. par->manual_standby = 1;
  710. }
  711. gpio_direction_output(board->gpio_nsleep, 0);
  712. }
  713. msleep(100);
  714. return 0;
  715. }
  716. static int auok190x_resume(struct device *dev)
  717. {
  718. struct platform_device *pdev = to_platform_device(dev);
  719. struct fb_info *info = platform_get_drvdata(pdev);
  720. struct auok190xfb_par *par = info->par;
  721. struct auok190x_board *board = par->board;
  722. dev_dbg(dev, "resume\n");
  723. if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) {
  724. dev_dbg(dev, "resume with broken standby\n");
  725. auok190x_power(par, 1);
  726. par->init(par);
  727. } else {
  728. dev_dbg(dev, "resume from sleep\n");
  729. /* device should be in runtime suspend when we were suspended
  730. * and pm_runtime_put_sync gets called after this function.
  731. * So there is no need to touch the standby mode here at all.
  732. */
  733. gpio_direction_output(board->gpio_nsleep, 1);
  734. msleep(100);
  735. /* an additional init call seems to be necessary after sleep */
  736. auok190x_runtime_resume(dev);
  737. par->init(par);
  738. /* if we were runtime-suspended before, suspend again*/
  739. if (!par->manual_standby)
  740. auok190x_runtime_suspend(dev);
  741. else
  742. par->manual_standby = 0;
  743. }
  744. return 0;
  745. }
  746. #endif
  747. const struct dev_pm_ops auok190x_pm = {
  748. SET_RUNTIME_PM_OPS(auok190x_runtime_suspend, auok190x_runtime_resume,
  749. NULL)
  750. SET_SYSTEM_SLEEP_PM_OPS(auok190x_suspend, auok190x_resume)
  751. };
  752. EXPORT_SYMBOL_GPL(auok190x_pm);
  753. /*
  754. * Common probe and remove code
  755. */
  756. int auok190x_common_probe(struct platform_device *pdev,
  757. struct auok190x_init_data *init)
  758. {
  759. struct auok190x_board *board = init->board;
  760. struct auok190xfb_par *par;
  761. struct fb_info *info;
  762. struct panel_info *panel;
  763. int videomemorysize, ret;
  764. unsigned char *videomemory;
  765. /* check board contents */
  766. if (!board->init || !board->cleanup || !board->wait_for_rdy
  767. || !board->set_ctl || !board->set_hdb || !board->get_hdb
  768. || !board->setup_irq)
  769. return -EINVAL;
  770. info = framebuffer_alloc(sizeof(struct auok190xfb_par), &pdev->dev);
  771. if (!info)
  772. return -ENOMEM;
  773. par = info->par;
  774. par->info = info;
  775. par->board = board;
  776. par->recover = auok190x_recover;
  777. par->update_partial = init->update_partial;
  778. par->update_all = init->update_all;
  779. par->need_refresh = init->need_refresh;
  780. par->init = init->init;
  781. /* init update modes */
  782. par->update_cnt = 0;
  783. par->update_mode = -1;
  784. par->last_mode = -1;
  785. par->flash = 0;
  786. par->regulator = regulator_get(info->device, "vdd");
  787. if (IS_ERR(par->regulator)) {
  788. ret = PTR_ERR(par->regulator);
  789. dev_err(info->device, "Failed to get regulator: %d\n", ret);
  790. goto err_reg;
  791. }
  792. ret = board->init(par);
  793. if (ret) {
  794. dev_err(info->device, "board init failed, %d\n", ret);
  795. goto err_board;
  796. }
  797. ret = gpio_request(board->gpio_nsleep, "AUOK190x sleep");
  798. if (ret) {
  799. dev_err(info->device, "could not request sleep gpio, %d\n",
  800. ret);
  801. goto err_gpio1;
  802. }
  803. ret = gpio_direction_output(board->gpio_nsleep, 0);
  804. if (ret) {
  805. dev_err(info->device, "could not set sleep gpio, %d\n", ret);
  806. goto err_gpio2;
  807. }
  808. ret = gpio_request(board->gpio_nrst, "AUOK190x reset");
  809. if (ret) {
  810. dev_err(info->device, "could not request reset gpio, %d\n",
  811. ret);
  812. goto err_gpio2;
  813. }
  814. ret = gpio_direction_output(board->gpio_nrst, 0);
  815. if (ret) {
  816. dev_err(info->device, "could not set reset gpio, %d\n", ret);
  817. goto err_gpio3;
  818. }
  819. ret = auok190x_power(par, 1);
  820. if (ret) {
  821. dev_err(info->device, "could not power on the device, %d\n",
  822. ret);
  823. goto err_gpio3;
  824. }
  825. mutex_init(&par->io_lock);
  826. init_waitqueue_head(&par->waitq);
  827. ret = par->board->setup_irq(par->info);
  828. if (ret) {
  829. dev_err(info->device, "could not setup ready-irq, %d\n", ret);
  830. goto err_irq;
  831. }
  832. /* wait for init to complete */
  833. par->board->wait_for_rdy(par);
  834. /*
  835. * From here on the controller can talk to us
  836. */
  837. /* initialise fix, var, resolution and rotation */
  838. strlcpy(info->fix.id, init->id, 16);
  839. info->var.bits_per_pixel = 8;
  840. info->var.grayscale = 1;
  841. panel = &panel_table[board->resolution];
  842. par->resolution = board->resolution;
  843. par->rotation = 0;
  844. /* videomemory handling */
  845. videomemorysize = roundup((panel->w * panel->h) * 2, PAGE_SIZE);
  846. videomemory = vmalloc(videomemorysize);
  847. if (!videomemory) {
  848. ret = -ENOMEM;
  849. goto err_irq;
  850. }
  851. memset(videomemory, 0, videomemorysize);
  852. info->screen_base = (char *)videomemory;
  853. info->fix.smem_len = videomemorysize;
  854. info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
  855. info->fbops = &auok190xfb_ops;
  856. ret = auok190xfb_check_var(&info->var, info);
  857. if (ret)
  858. goto err_defio;
  859. auok190xfb_set_fix(info);
  860. /* deferred io init */
  861. info->fbdefio = devm_kzalloc(info->device,
  862. sizeof(struct fb_deferred_io),
  863. GFP_KERNEL);
  864. if (!info->fbdefio) {
  865. dev_err(info->device, "Failed to allocate memory\n");
  866. ret = -ENOMEM;
  867. goto err_defio;
  868. }
  869. dev_dbg(info->device, "targeting %d frames per second\n", board->fps);
  870. info->fbdefio->delay = HZ / board->fps;
  871. info->fbdefio->first_io = auok190xfb_dpy_first_io,
  872. info->fbdefio->deferred_io = auok190xfb_dpy_deferred_io,
  873. fb_deferred_io_init(info);
  874. /* color map */
  875. ret = fb_alloc_cmap(&info->cmap, 256, 0);
  876. if (ret < 0) {
  877. dev_err(info->device, "Failed to allocate colormap\n");
  878. goto err_cmap;
  879. }
  880. /* controller init */
  881. par->consecutive_threshold = 100;
  882. par->init(par);
  883. auok190x_identify(par);
  884. platform_set_drvdata(pdev, info);
  885. ret = register_framebuffer(info);
  886. if (ret < 0)
  887. goto err_regfb;
  888. ret = sysfs_create_group(&info->device->kobj, &auok190x_attr_group);
  889. if (ret)
  890. goto err_sysfs;
  891. dev_info(info->device, "fb%d: %dx%d using %dK of video memory\n",
  892. info->node, info->var.xres, info->var.yres,
  893. videomemorysize >> 10);
  894. /* increase autosuspend_delay when we use alternative methods
  895. * for runtime_pm
  896. */
  897. par->autosuspend_delay = (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN)
  898. ? 1000 : 200;
  899. pm_runtime_set_active(info->device);
  900. pm_runtime_enable(info->device);
  901. pm_runtime_set_autosuspend_delay(info->device, par->autosuspend_delay);
  902. pm_runtime_use_autosuspend(info->device);
  903. return 0;
  904. err_sysfs:
  905. unregister_framebuffer(info);
  906. err_regfb:
  907. fb_dealloc_cmap(&info->cmap);
  908. err_cmap:
  909. fb_deferred_io_cleanup(info);
  910. err_defio:
  911. vfree((void *)info->screen_base);
  912. err_irq:
  913. auok190x_power(par, 0);
  914. err_gpio3:
  915. gpio_free(board->gpio_nrst);
  916. err_gpio2:
  917. gpio_free(board->gpio_nsleep);
  918. err_gpio1:
  919. board->cleanup(par);
  920. err_board:
  921. regulator_put(par->regulator);
  922. err_reg:
  923. framebuffer_release(info);
  924. return ret;
  925. }
  926. EXPORT_SYMBOL_GPL(auok190x_common_probe);
  927. int auok190x_common_remove(struct platform_device *pdev)
  928. {
  929. struct fb_info *info = platform_get_drvdata(pdev);
  930. struct auok190xfb_par *par = info->par;
  931. struct auok190x_board *board = par->board;
  932. pm_runtime_disable(info->device);
  933. sysfs_remove_group(&info->device->kobj, &auok190x_attr_group);
  934. unregister_framebuffer(info);
  935. fb_dealloc_cmap(&info->cmap);
  936. fb_deferred_io_cleanup(info);
  937. vfree((void *)info->screen_base);
  938. auok190x_power(par, 0);
  939. gpio_free(board->gpio_nrst);
  940. gpio_free(board->gpio_nsleep);
  941. board->cleanup(par);
  942. regulator_put(par->regulator);
  943. framebuffer_release(info);
  944. return 0;
  945. }
  946. EXPORT_SYMBOL_GPL(auok190x_common_remove);
  947. MODULE_DESCRIPTION("Common code for AUO-K190X controllers");
  948. MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
  949. MODULE_LICENSE("GPL");