Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

video: fbdev: remove unused auo_k190xfb drivers

auo_k1900fb and auo_k1901fb drivers have been introduced six
years ago by following commits:

commit 2c8304d3125b ("video: auo_k190x: add code shared by controller drivers")
commit 96b1d500e028 ("video: auo_k190x: add driver for AUO-K1900 variant")
commit 53027cdf2a67 ("video: auo_k190x: add driver for AUO-K1901 variant")

They never had any in-kernel user so just remove them (since
they are platform drivers they need corresponding platform
devices to be registered by kernel and it has never happened).

Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>

-1923
-33
drivers/video/fbdev/Kconfig
··· 2253 2253 and could also have been called by other names when coupled with 2254 2254 a bridge adapter. 2255 2255 2256 - config FB_AUO_K190X 2257 - tristate "AUO-K190X EPD controller support" 2258 - depends on FB 2259 - select FB_SYS_FILLRECT 2260 - select FB_SYS_COPYAREA 2261 - select FB_SYS_IMAGEBLIT 2262 - select FB_SYS_FOPS 2263 - select FB_DEFERRED_IO 2264 - help 2265 - Provides support for epaper controllers from the K190X series 2266 - of AUO. These controllers can be used to drive epaper displays 2267 - from Sipix. 2268 - 2269 - This option enables the common support, shared by the individual 2270 - controller drivers. You will also have to enable the driver 2271 - for the controller type used in your device. 2272 - 2273 - config FB_AUO_K1900 2274 - tristate "AUO-K1900 EPD controller support" 2275 - depends on FB && FB_AUO_K190X 2276 - help 2277 - This driver implements support for the AUO K1900 epd-controller. 2278 - This controller can drive Sipix epaper displays but can only do 2279 - serial updates, reducing the number of possible frames per second. 2280 - 2281 - config FB_AUO_K1901 2282 - tristate "AUO-K1901 EPD controller support" 2283 - depends on FB && FB_AUO_K190X 2284 - help 2285 - This driver implements support for the AUO K1901 epd-controller. 2286 - This controller can drive Sipix epaper displays and supports 2287 - concurrent updates, making higher frames per second possible. 2288 - 2289 2256 config FB_JZ4740 2290 2257 tristate "JZ4740 LCD framebuffer support" 2291 2258 depends on FB && MACH_JZ4740
-3
drivers/video/fbdev/Makefile
··· 100 100 obj-$(CONFIG_FB_MAXINE) += maxinefb.o 101 101 obj-$(CONFIG_FB_METRONOME) += metronomefb.o 102 102 obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o 103 - obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o 104 - obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o 105 - obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o 106 103 obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 107 104 obj-$(CONFIG_FB_SH7760) += sh7760fb.o 108 105 obj-$(CONFIG_FB_IMX) += imxfb.o
-204
drivers/video/fbdev/auo_k1900fb.c
··· 1 - /* 2 - * auok190xfb.c -- FB driver for AUO-K1900 controllers 3 - * 4 - * Copyright (C) 2011, 2012 Heiko Stuebner <heiko@sntech.de> 5 - * 6 - * based on broadsheetfb.c 7 - * 8 - * Copyright (C) 2008, Jaya Kumar 9 - * 10 - * This program is free software; you can redistribute it and/or modify 11 - * it under the terms of the GNU General Public License version 2 as 12 - * published by the Free Software Foundation. 13 - * 14 - * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. 15 - * 16 - * This driver is written to be used with the AUO-K1900 display controller. 17 - * 18 - * It is intended to be architecture independent. A board specific driver 19 - * must be used to perform all the physical IO interactions. 20 - * 21 - * The controller supports different update modes: 22 - * mode0+1 16 step gray (4bit) 23 - * mode2 4 step gray (2bit) - FIXME: add strange refresh 24 - * mode3 2 step gray (1bit) - FIXME: add strange refresh 25 - * mode4 handwriting mode (strange behaviour) 26 - * mode5 automatic selection of update mode 27 - */ 28 - 29 - #include <linux/module.h> 30 - #include <linux/kernel.h> 31 - #include <linux/errno.h> 32 - #include <linux/string.h> 33 - #include <linux/mm.h> 34 - #include <linux/slab.h> 35 - #include <linux/delay.h> 36 - #include <linux/interrupt.h> 37 - #include <linux/fb.h> 38 - #include <linux/init.h> 39 - #include <linux/platform_device.h> 40 - #include <linux/list.h> 41 - #include <linux/firmware.h> 42 - #include <linux/gpio.h> 43 - #include <linux/pm_runtime.h> 44 - 45 - #include <video/auo_k190xfb.h> 46 - 47 - #include "auo_k190x.h" 48 - 49 - /* 50 - * AUO-K1900 specific commands 51 - */ 52 - 53 - #define AUOK1900_CMD_PARTIALDISP 0x1001 54 - #define AUOK1900_CMD_ROTATION 0x1006 55 - #define AUOK1900_CMD_LUT_STOP 0x1009 56 - 57 - #define AUOK1900_INIT_TEMP_AVERAGE (1 << 13) 58 - #define AUOK1900_INIT_ROTATE(_x) ((_x & 0x3) << 10) 59 - #define AUOK1900_INIT_RESOLUTION(_res) ((_res & 0x7) << 2) 60 - 61 - static void auok1900_init(struct auok190xfb_par *par) 62 - { 63 - struct device *dev = par->info->device; 64 - struct auok190x_board *board = par->board; 65 - u16 init_param = 0; 66 - 67 - pm_runtime_get_sync(dev); 68 - 69 - init_param |= AUOK1900_INIT_TEMP_AVERAGE; 70 - init_param |= AUOK1900_INIT_ROTATE(par->rotation); 71 - init_param |= AUOK190X_INIT_INVERSE_WHITE; 72 - init_param |= AUOK190X_INIT_FORMAT0; 73 - init_param |= AUOK1900_INIT_RESOLUTION(par->resolution); 74 - init_param |= AUOK190X_INIT_SHIFT_RIGHT; 75 - 76 - auok190x_send_cmdargs(par, AUOK190X_CMD_INIT, 1, &init_param); 77 - 78 - /* let the controller finish */ 79 - board->wait_for_rdy(par); 80 - 81 - pm_runtime_mark_last_busy(dev); 82 - pm_runtime_put_autosuspend(dev); 83 - } 84 - 85 - static void auok1900_update_region(struct auok190xfb_par *par, int mode, 86 - u16 y1, u16 y2) 87 - { 88 - struct device *dev = par->info->device; 89 - unsigned char *buf = (unsigned char *)par->info->screen_base; 90 - int xres = par->info->var.xres; 91 - int line_length = par->info->fix.line_length; 92 - u16 args[4]; 93 - 94 - pm_runtime_get_sync(dev); 95 - 96 - mutex_lock(&(par->io_lock)); 97 - 98 - /* y1 and y2 must be a multiple of 2 so drop the lowest bit */ 99 - y1 &= 0xfffe; 100 - y2 &= 0xfffe; 101 - 102 - dev_dbg(dev, "update (x,y,w,h,mode)=(%d,%d,%d,%d,%d)\n", 103 - 1, y1+1, xres, y2-y1, mode); 104 - 105 - /* to FIX handle different partial update modes */ 106 - args[0] = mode | 1; 107 - args[1] = y1 + 1; 108 - args[2] = xres; 109 - args[3] = y2 - y1; 110 - buf += y1 * line_length; 111 - auok190x_send_cmdargs_pixels(par, AUOK1900_CMD_PARTIALDISP, 4, args, 112 - ((y2 - y1) * line_length)/2, (u16 *) buf); 113 - auok190x_send_command(par, AUOK190X_CMD_DATA_STOP); 114 - 115 - par->update_cnt++; 116 - 117 - mutex_unlock(&(par->io_lock)); 118 - 119 - pm_runtime_mark_last_busy(dev); 120 - pm_runtime_put_autosuspend(dev); 121 - } 122 - 123 - static void auok1900fb_dpy_update_pages(struct auok190xfb_par *par, 124 - u16 y1, u16 y2) 125 - { 126 - int mode; 127 - 128 - if (par->update_mode < 0) { 129 - mode = AUOK190X_UPDATE_MODE(1); 130 - par->last_mode = -1; 131 - } else { 132 - mode = AUOK190X_UPDATE_MODE(par->update_mode); 133 - par->last_mode = par->update_mode; 134 - } 135 - 136 - if (par->flash) 137 - mode |= AUOK190X_UPDATE_NONFLASH; 138 - 139 - auok1900_update_region(par, mode, y1, y2); 140 - } 141 - 142 - static void auok1900fb_dpy_update(struct auok190xfb_par *par) 143 - { 144 - int mode; 145 - 146 - if (par->update_mode < 0) { 147 - mode = AUOK190X_UPDATE_MODE(0); 148 - par->last_mode = -1; 149 - } else { 150 - mode = AUOK190X_UPDATE_MODE(par->update_mode); 151 - par->last_mode = par->update_mode; 152 - } 153 - 154 - if (par->flash) 155 - mode |= AUOK190X_UPDATE_NONFLASH; 156 - 157 - auok1900_update_region(par, mode, 0, par->info->var.yres); 158 - par->update_cnt = 0; 159 - } 160 - 161 - static bool auok1900fb_need_refresh(struct auok190xfb_par *par) 162 - { 163 - return (par->update_cnt > 10); 164 - } 165 - 166 - static int auok1900fb_probe(struct platform_device *pdev) 167 - { 168 - struct auok190x_init_data init; 169 - struct auok190x_board *board; 170 - 171 - /* pick up board specific routines */ 172 - board = pdev->dev.platform_data; 173 - if (!board) 174 - return -EINVAL; 175 - 176 - /* fill temporary init struct for common init */ 177 - init.id = "auo_k1900fb"; 178 - init.board = board; 179 - init.update_partial = auok1900fb_dpy_update_pages; 180 - init.update_all = auok1900fb_dpy_update; 181 - init.need_refresh = auok1900fb_need_refresh; 182 - init.init = auok1900_init; 183 - 184 - return auok190x_common_probe(pdev, &init); 185 - } 186 - 187 - static int auok1900fb_remove(struct platform_device *pdev) 188 - { 189 - return auok190x_common_remove(pdev); 190 - } 191 - 192 - static struct platform_driver auok1900fb_driver = { 193 - .probe = auok1900fb_probe, 194 - .remove = auok1900fb_remove, 195 - .driver = { 196 - .name = "auo_k1900fb", 197 - .pm = &auok190x_pm, 198 - }, 199 - }; 200 - module_platform_driver(auok1900fb_driver); 201 - 202 - MODULE_DESCRIPTION("framebuffer driver for the AUO-K1900 EPD controller"); 203 - MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 204 - MODULE_LICENSE("GPL");
-257
drivers/video/fbdev/auo_k1901fb.c
··· 1 - /* 2 - * auok190xfb.c -- FB driver for AUO-K1901 controllers 3 - * 4 - * Copyright (C) 2011, 2012 Heiko Stuebner <heiko@sntech.de> 5 - * 6 - * based on broadsheetfb.c 7 - * 8 - * Copyright (C) 2008, Jaya Kumar 9 - * 10 - * This program is free software; you can redistribute it and/or modify 11 - * it under the terms of the GNU General Public License version 2 as 12 - * published by the Free Software Foundation. 13 - * 14 - * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. 15 - * 16 - * This driver is written to be used with the AUO-K1901 display controller. 17 - * 18 - * It is intended to be architecture independent. A board specific driver 19 - * must be used to perform all the physical IO interactions. 20 - * 21 - * The controller supports different update modes: 22 - * mode0+1 16 step gray (4bit) 23 - * mode2+3 4 step gray (2bit) 24 - * mode4+5 2 step gray (1bit) 25 - * - mode4 is described as "without LUT" 26 - * mode7 automatic selection of update mode 27 - * 28 - * The most interesting difference to the K1900 is the ability to do screen 29 - * updates in an asynchronous fashion. Where the K1900 needs to wait for the 30 - * current update to complete, the K1901 can process later updates already. 31 - */ 32 - 33 - #include <linux/module.h> 34 - #include <linux/kernel.h> 35 - #include <linux/errno.h> 36 - #include <linux/string.h> 37 - #include <linux/mm.h> 38 - #include <linux/slab.h> 39 - #include <linux/delay.h> 40 - #include <linux/interrupt.h> 41 - #include <linux/fb.h> 42 - #include <linux/init.h> 43 - #include <linux/platform_device.h> 44 - #include <linux/list.h> 45 - #include <linux/firmware.h> 46 - #include <linux/gpio.h> 47 - #include <linux/pm_runtime.h> 48 - 49 - #include <video/auo_k190xfb.h> 50 - 51 - #include "auo_k190x.h" 52 - 53 - /* 54 - * AUO-K1901 specific commands 55 - */ 56 - 57 - #define AUOK1901_CMD_LUT_INTERFACE 0x0005 58 - #define AUOK1901_CMD_DMA_START 0x1001 59 - #define AUOK1901_CMD_CURSOR_START 0x1007 60 - #define AUOK1901_CMD_CURSOR_STOP AUOK190X_CMD_DATA_STOP 61 - #define AUOK1901_CMD_DDMA_START 0x1009 62 - 63 - #define AUOK1901_INIT_GATE_PULSE_LOW (0 << 14) 64 - #define AUOK1901_INIT_GATE_PULSE_HIGH (1 << 14) 65 - #define AUOK1901_INIT_SINGLE_GATE (0 << 13) 66 - #define AUOK1901_INIT_DOUBLE_GATE (1 << 13) 67 - 68 - /* Bits to pixels 69 - * Mode 15-12 11-8 7-4 3-0 70 - * format2 2 T 1 T 71 - * format3 1 T 2 T 72 - * format4 T 2 T 1 73 - * format5 T 1 T 2 74 - * 75 - * halftone modes: 76 - * format6 2 2 1 1 77 - * format7 1 1 2 2 78 - */ 79 - #define AUOK1901_INIT_FORMAT2 (1 << 7) 80 - #define AUOK1901_INIT_FORMAT3 ((1 << 7) | (1 << 6)) 81 - #define AUOK1901_INIT_FORMAT4 (1 << 8) 82 - #define AUOK1901_INIT_FORMAT5 ((1 << 8) | (1 << 6)) 83 - #define AUOK1901_INIT_FORMAT6 ((1 << 8) | (1 << 7)) 84 - #define AUOK1901_INIT_FORMAT7 ((1 << 8) | (1 << 7) | (1 << 6)) 85 - 86 - /* res[4] to bit 10 87 - * res[3-0] to bits 5-2 88 - */ 89 - #define AUOK1901_INIT_RESOLUTION(_res) (((_res & (1 << 4)) << 6) \ 90 - | ((_res & 0xf) << 2)) 91 - 92 - /* 93 - * portrait / landscape orientation in AUOK1901_CMD_DMA_START 94 - */ 95 - #define AUOK1901_DMA_ROTATE90(_rot) ((_rot & 1) << 13) 96 - 97 - /* 98 - * equivalent to 1 << 11, needs the ~ to have same rotation like K1900 99 - */ 100 - #define AUOK1901_DDMA_ROTATE180(_rot) ((~_rot & 2) << 10) 101 - 102 - static void auok1901_init(struct auok190xfb_par *par) 103 - { 104 - struct device *dev = par->info->device; 105 - struct auok190x_board *board = par->board; 106 - u16 init_param = 0; 107 - 108 - pm_runtime_get_sync(dev); 109 - 110 - init_param |= AUOK190X_INIT_INVERSE_WHITE; 111 - init_param |= AUOK190X_INIT_FORMAT0; 112 - init_param |= AUOK1901_INIT_RESOLUTION(par->resolution); 113 - init_param |= AUOK190X_INIT_SHIFT_LEFT; 114 - 115 - auok190x_send_cmdargs(par, AUOK190X_CMD_INIT, 1, &init_param); 116 - 117 - /* let the controller finish */ 118 - board->wait_for_rdy(par); 119 - 120 - pm_runtime_mark_last_busy(dev); 121 - pm_runtime_put_autosuspend(dev); 122 - } 123 - 124 - static void auok1901_update_region(struct auok190xfb_par *par, int mode, 125 - u16 y1, u16 y2) 126 - { 127 - struct device *dev = par->info->device; 128 - unsigned char *buf = (unsigned char *)par->info->screen_base; 129 - int xres = par->info->var.xres; 130 - int line_length = par->info->fix.line_length; 131 - u16 args[5]; 132 - 133 - pm_runtime_get_sync(dev); 134 - 135 - mutex_lock(&(par->io_lock)); 136 - 137 - /* y1 and y2 must be a multiple of 2 so drop the lowest bit */ 138 - y1 &= 0xfffe; 139 - y2 &= 0xfffe; 140 - 141 - dev_dbg(dev, "update (x,y,w,h,mode)=(%d,%d,%d,%d,%d)\n", 142 - 1, y1+1, xres, y2-y1, mode); 143 - 144 - /* K1901: first transfer the region data */ 145 - args[0] = AUOK1901_DMA_ROTATE90(par->rotation) | 1; 146 - args[1] = y1 + 1; 147 - args[2] = xres; 148 - args[3] = y2 - y1; 149 - buf += y1 * line_length; 150 - auok190x_send_cmdargs_pixels_nowait(par, AUOK1901_CMD_DMA_START, 4, 151 - args, ((y2 - y1) * line_length)/2, 152 - (u16 *) buf); 153 - auok190x_send_command_nowait(par, AUOK190X_CMD_DATA_STOP); 154 - 155 - /* K1901: second tell the controller to update the region with mode */ 156 - args[0] = mode | AUOK1901_DDMA_ROTATE180(par->rotation); 157 - args[1] = 1; 158 - args[2] = y1 + 1; 159 - args[3] = xres; 160 - args[4] = y2 - y1; 161 - auok190x_send_cmdargs_nowait(par, AUOK1901_CMD_DDMA_START, 5, args); 162 - 163 - par->update_cnt++; 164 - 165 - mutex_unlock(&(par->io_lock)); 166 - 167 - pm_runtime_mark_last_busy(dev); 168 - pm_runtime_put_autosuspend(dev); 169 - } 170 - 171 - static void auok1901fb_dpy_update_pages(struct auok190xfb_par *par, 172 - u16 y1, u16 y2) 173 - { 174 - int mode; 175 - 176 - if (par->update_mode < 0) { 177 - mode = AUOK190X_UPDATE_MODE(1); 178 - par->last_mode = -1; 179 - } else { 180 - mode = AUOK190X_UPDATE_MODE(par->update_mode); 181 - par->last_mode = par->update_mode; 182 - } 183 - 184 - if (par->flash) 185 - mode |= AUOK190X_UPDATE_NONFLASH; 186 - 187 - auok1901_update_region(par, mode, y1, y2); 188 - } 189 - 190 - static void auok1901fb_dpy_update(struct auok190xfb_par *par) 191 - { 192 - int mode; 193 - 194 - /* When doing full updates, wait for the controller to be ready 195 - * This will hopefully catch some hangs of the K1901 196 - */ 197 - par->board->wait_for_rdy(par); 198 - 199 - if (par->update_mode < 0) { 200 - mode = AUOK190X_UPDATE_MODE(0); 201 - par->last_mode = -1; 202 - } else { 203 - mode = AUOK190X_UPDATE_MODE(par->update_mode); 204 - par->last_mode = par->update_mode; 205 - } 206 - 207 - if (par->flash) 208 - mode |= AUOK190X_UPDATE_NONFLASH; 209 - 210 - auok1901_update_region(par, mode, 0, par->info->var.yres); 211 - par->update_cnt = 0; 212 - } 213 - 214 - static bool auok1901fb_need_refresh(struct auok190xfb_par *par) 215 - { 216 - return (par->update_cnt > 10); 217 - } 218 - 219 - static int auok1901fb_probe(struct platform_device *pdev) 220 - { 221 - struct auok190x_init_data init; 222 - struct auok190x_board *board; 223 - 224 - /* pick up board specific routines */ 225 - board = pdev->dev.platform_data; 226 - if (!board) 227 - return -EINVAL; 228 - 229 - /* fill temporary init struct for common init */ 230 - init.id = "auo_k1901fb"; 231 - init.board = board; 232 - init.update_partial = auok1901fb_dpy_update_pages; 233 - init.update_all = auok1901fb_dpy_update; 234 - init.need_refresh = auok1901fb_need_refresh; 235 - init.init = auok1901_init; 236 - 237 - return auok190x_common_probe(pdev, &init); 238 - } 239 - 240 - static int auok1901fb_remove(struct platform_device *pdev) 241 - { 242 - return auok190x_common_remove(pdev); 243 - } 244 - 245 - static struct platform_driver auok1901fb_driver = { 246 - .probe = auok1901fb_probe, 247 - .remove = auok1901fb_remove, 248 - .driver = { 249 - .name = "auo_k1901fb", 250 - .pm = &auok190x_pm, 251 - }, 252 - }; 253 - module_platform_driver(auok1901fb_driver); 254 - 255 - MODULE_DESCRIPTION("framebuffer driver for the AUO-K1901 EPD controller"); 256 - MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 257 - MODULE_LICENSE("GPL");
-1190
drivers/video/fbdev/auo_k190x.c
··· 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 - 11 - #include <linux/module.h> 12 - #include <linux/sched/mm.h> 13 - #include <linux/kernel.h> 14 - #include <linux/gpio.h> 15 - #include <linux/platform_device.h> 16 - #include <linux/pm_runtime.h> 17 - #include <linux/fb.h> 18 - #include <linux/delay.h> 19 - #include <linux/uaccess.h> 20 - #include <linux/vmalloc.h> 21 - #include <linux/regulator/consumer.h> 22 - 23 - #include <video/auo_k190xfb.h> 24 - 25 - #include "auo_k190x.h" 26 - 27 - struct panel_info { 28 - int w; 29 - int h; 30 - }; 31 - 32 - /* table of panel specific parameters to be indexed into by the board drivers */ 33 - static struct panel_info panel_table[] = { 34 - /* standard 6" */ 35 - [AUOK190X_RESOLUTION_800_600] = { 36 - .w = 800, 37 - .h = 600, 38 - }, 39 - /* standard 9" */ 40 - [AUOK190X_RESOLUTION_1024_768] = { 41 - .w = 1024, 42 - .h = 768, 43 - }, 44 - [AUOK190X_RESOLUTION_600_800] = { 45 - .w = 600, 46 - .h = 800, 47 - }, 48 - [AUOK190X_RESOLUTION_768_1024] = { 49 - .w = 768, 50 - .h = 1024, 51 - }, 52 - }; 53 - 54 - /* 55 - * private I80 interface to the board driver 56 - */ 57 - 58 - static void auok190x_issue_data(struct auok190xfb_par *par, u16 data) 59 - { 60 - par->board->set_ctl(par, AUOK190X_I80_WR, 0); 61 - par->board->set_hdb(par, data); 62 - par->board->set_ctl(par, AUOK190X_I80_WR, 1); 63 - } 64 - 65 - static void auok190x_issue_cmd(struct auok190xfb_par *par, u16 data) 66 - { 67 - par->board->set_ctl(par, AUOK190X_I80_DC, 0); 68 - auok190x_issue_data(par, data); 69 - par->board->set_ctl(par, AUOK190X_I80_DC, 1); 70 - } 71 - 72 - /** 73 - * Conversion of 16bit color to 4bit grayscale 74 - * does roughly (0.3 * R + 0.6 G + 0.1 B) / 2 75 - */ 76 - static inline int rgb565_to_gray4(u16 data, struct fb_var_screeninfo *var) 77 - { 78 - return ((((data & 0xF800) >> var->red.offset) * 77 + 79 - ((data & 0x07E0) >> (var->green.offset + 1)) * 151 + 80 - ((data & 0x1F) >> var->blue.offset) * 28) >> 8 >> 1); 81 - } 82 - 83 - static int auok190x_issue_pixels_rgb565(struct auok190xfb_par *par, int size, 84 - u16 *data) 85 - { 86 - struct fb_var_screeninfo *var = &par->info->var; 87 - struct device *dev = par->info->device; 88 - int i; 89 - u16 tmp; 90 - 91 - if (size & 7) { 92 - dev_err(dev, "issue_pixels: size %d must be a multiple of 8\n", 93 - size); 94 - return -EINVAL; 95 - } 96 - 97 - for (i = 0; i < (size >> 2); i++) { 98 - par->board->set_ctl(par, AUOK190X_I80_WR, 0); 99 - 100 - tmp = (rgb565_to_gray4(data[4*i], var) & 0x000F); 101 - tmp |= (rgb565_to_gray4(data[4*i+1], var) << 4) & 0x00F0; 102 - tmp |= (rgb565_to_gray4(data[4*i+2], var) << 8) & 0x0F00; 103 - tmp |= (rgb565_to_gray4(data[4*i+3], var) << 12) & 0xF000; 104 - 105 - par->board->set_hdb(par, tmp); 106 - par->board->set_ctl(par, AUOK190X_I80_WR, 1); 107 - } 108 - 109 - return 0; 110 - } 111 - 112 - static int auok190x_issue_pixels_gray8(struct auok190xfb_par *par, int size, 113 - u16 *data) 114 - { 115 - struct device *dev = par->info->device; 116 - int i; 117 - u16 tmp; 118 - 119 - if (size & 3) { 120 - dev_err(dev, "issue_pixels: size %d must be a multiple of 4\n", 121 - size); 122 - return -EINVAL; 123 - } 124 - 125 - for (i = 0; i < (size >> 1); i++) { 126 - par->board->set_ctl(par, AUOK190X_I80_WR, 0); 127 - 128 - /* simple reduction of 8bit staticgray to 4bit gray 129 - * combines 4 * 4bit pixel values into a 16bit value 130 - */ 131 - tmp = (data[2*i] & 0xF0) >> 4; 132 - tmp |= (data[2*i] & 0xF000) >> 8; 133 - tmp |= (data[2*i+1] & 0xF0) << 4; 134 - tmp |= (data[2*i+1] & 0xF000); 135 - 136 - par->board->set_hdb(par, tmp); 137 - par->board->set_ctl(par, AUOK190X_I80_WR, 1); 138 - } 139 - 140 - return 0; 141 - } 142 - 143 - static int auok190x_issue_pixels(struct auok190xfb_par *par, int size, 144 - u16 *data) 145 - { 146 - struct fb_info *info = par->info; 147 - struct device *dev = par->info->device; 148 - 149 - if (info->var.bits_per_pixel == 8 && info->var.grayscale) 150 - auok190x_issue_pixels_gray8(par, size, data); 151 - else if (info->var.bits_per_pixel == 16) 152 - auok190x_issue_pixels_rgb565(par, size, data); 153 - else 154 - dev_err(dev, "unsupported color mode (bits: %d, gray: %d)\n", 155 - info->var.bits_per_pixel, info->var.grayscale); 156 - 157 - return 0; 158 - } 159 - 160 - static u16 auok190x_read_data(struct auok190xfb_par *par) 161 - { 162 - u16 data; 163 - 164 - par->board->set_ctl(par, AUOK190X_I80_OE, 0); 165 - data = par->board->get_hdb(par); 166 - par->board->set_ctl(par, AUOK190X_I80_OE, 1); 167 - 168 - return data; 169 - } 170 - 171 - /* 172 - * Command interface for the controller drivers 173 - */ 174 - 175 - void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data) 176 - { 177 - par->board->set_ctl(par, AUOK190X_I80_CS, 0); 178 - auok190x_issue_cmd(par, data); 179 - par->board->set_ctl(par, AUOK190X_I80_CS, 1); 180 - } 181 - EXPORT_SYMBOL_GPL(auok190x_send_command_nowait); 182 - 183 - void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd, 184 - int argc, u16 *argv) 185 - { 186 - int i; 187 - 188 - par->board->set_ctl(par, AUOK190X_I80_CS, 0); 189 - auok190x_issue_cmd(par, cmd); 190 - 191 - for (i = 0; i < argc; i++) 192 - auok190x_issue_data(par, argv[i]); 193 - par->board->set_ctl(par, AUOK190X_I80_CS, 1); 194 - } 195 - EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_nowait); 196 - 197 - int auok190x_send_command(struct auok190xfb_par *par, u16 data) 198 - { 199 - int ret; 200 - 201 - ret = par->board->wait_for_rdy(par); 202 - if (ret) 203 - return ret; 204 - 205 - auok190x_send_command_nowait(par, data); 206 - return 0; 207 - } 208 - EXPORT_SYMBOL_GPL(auok190x_send_command); 209 - 210 - int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd, 211 - int argc, u16 *argv) 212 - { 213 - int ret; 214 - 215 - ret = par->board->wait_for_rdy(par); 216 - if (ret) 217 - return ret; 218 - 219 - auok190x_send_cmdargs_nowait(par, cmd, argc, argv); 220 - return 0; 221 - } 222 - EXPORT_SYMBOL_GPL(auok190x_send_cmdargs); 223 - 224 - int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd, 225 - int argc, u16 *argv) 226 - { 227 - int i, ret; 228 - 229 - ret = par->board->wait_for_rdy(par); 230 - if (ret) 231 - return ret; 232 - 233 - par->board->set_ctl(par, AUOK190X_I80_CS, 0); 234 - auok190x_issue_cmd(par, cmd); 235 - 236 - for (i = 0; i < argc; i++) 237 - argv[i] = auok190x_read_data(par); 238 - par->board->set_ctl(par, AUOK190X_I80_CS, 1); 239 - 240 - return 0; 241 - } 242 - EXPORT_SYMBOL_GPL(auok190x_read_cmdargs); 243 - 244 - void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par, u16 cmd, 245 - int argc, u16 *argv, int size, u16 *data) 246 - { 247 - int i; 248 - 249 - par->board->set_ctl(par, AUOK190X_I80_CS, 0); 250 - 251 - auok190x_issue_cmd(par, cmd); 252 - 253 - for (i = 0; i < argc; i++) 254 - auok190x_issue_data(par, argv[i]); 255 - 256 - auok190x_issue_pixels(par, size, data); 257 - 258 - par->board->set_ctl(par, AUOK190X_I80_CS, 1); 259 - } 260 - EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels_nowait); 261 - 262 - int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd, 263 - int argc, u16 *argv, int size, u16 *data) 264 - { 265 - int ret; 266 - 267 - ret = par->board->wait_for_rdy(par); 268 - if (ret) 269 - return ret; 270 - 271 - auok190x_send_cmdargs_pixels_nowait(par, cmd, argc, argv, size, data); 272 - 273 - return 0; 274 - } 275 - EXPORT_SYMBOL_GPL(auok190x_send_cmdargs_pixels); 276 - 277 - /* 278 - * fbdefio callbacks - common on both controllers. 279 - */ 280 - 281 - static void auok190xfb_dpy_first_io(struct fb_info *info) 282 - { 283 - /* tell runtime-pm that we wish to use the device in a short time */ 284 - pm_runtime_get(info->device); 285 - } 286 - 287 - /* this is called back from the deferred io workqueue */ 288 - static void auok190xfb_dpy_deferred_io(struct fb_info *info, 289 - struct list_head *pagelist) 290 - { 291 - struct fb_deferred_io *fbdefio = info->fbdefio; 292 - struct auok190xfb_par *par = info->par; 293 - u16 line_length = info->fix.line_length; 294 - u16 yres = info->var.yres; 295 - u16 y1 = 0, h = 0; 296 - int prev_index = -1; 297 - struct page *cur; 298 - int h_inc; 299 - int threshold; 300 - 301 - if (!list_empty(pagelist)) 302 - /* the device resume should've been requested through first_io, 303 - * if the resume did not finish until now, wait for it. 304 - */ 305 - pm_runtime_barrier(info->device); 306 - else 307 - /* We reached this via the fsync or some other way. 308 - * In either case the first_io function did not run, 309 - * so we runtime_resume the device here synchronously. 310 - */ 311 - pm_runtime_get_sync(info->device); 312 - 313 - /* Do a full screen update every n updates to prevent 314 - * excessive darkening of the Sipix display. 315 - * If we do this, there is no need to walk the pages. 316 - */ 317 - if (par->need_refresh(par)) { 318 - par->update_all(par); 319 - goto out; 320 - } 321 - 322 - /* height increment is fixed per page */ 323 - h_inc = DIV_ROUND_UP(PAGE_SIZE , line_length); 324 - 325 - /* calculate number of pages from pixel height */ 326 - threshold = par->consecutive_threshold / h_inc; 327 - if (threshold < 1) 328 - threshold = 1; 329 - 330 - /* walk the written page list and swizzle the data */ 331 - list_for_each_entry(cur, &fbdefio->pagelist, lru) { 332 - if (prev_index < 0) { 333 - /* just starting so assign first page */ 334 - y1 = (cur->index << PAGE_SHIFT) / line_length; 335 - h = h_inc; 336 - } else if ((cur->index - prev_index) <= threshold) { 337 - /* page is within our threshold for single updates */ 338 - h += h_inc * (cur->index - prev_index); 339 - } else { 340 - /* page not consecutive, issue previous update first */ 341 - par->update_partial(par, y1, y1 + h); 342 - 343 - /* start over with our non consecutive page */ 344 - y1 = (cur->index << PAGE_SHIFT) / line_length; 345 - h = h_inc; 346 - } 347 - prev_index = cur->index; 348 - } 349 - 350 - /* if we still have any pages to update we do so now */ 351 - if (h >= yres) 352 - /* its a full screen update, just do it */ 353 - par->update_all(par); 354 - else 355 - par->update_partial(par, y1, min((u16) (y1 + h), yres)); 356 - 357 - out: 358 - pm_runtime_mark_last_busy(info->device); 359 - pm_runtime_put_autosuspend(info->device); 360 - } 361 - 362 - /* 363 - * framebuffer operations 364 - */ 365 - 366 - /* 367 - * this is the slow path from userspace. they can seek and write to 368 - * the fb. it's inefficient to do anything less than a full screen draw 369 - */ 370 - static ssize_t auok190xfb_write(struct fb_info *info, const char __user *buf, 371 - size_t count, loff_t *ppos) 372 - { 373 - struct auok190xfb_par *par = info->par; 374 - unsigned long p = *ppos; 375 - void *dst; 376 - int err = 0; 377 - unsigned long total_size; 378 - 379 - if (info->state != FBINFO_STATE_RUNNING) 380 - return -EPERM; 381 - 382 - total_size = info->fix.smem_len; 383 - 384 - if (p > total_size) 385 - return -EFBIG; 386 - 387 - if (count > total_size) { 388 - err = -EFBIG; 389 - count = total_size; 390 - } 391 - 392 - if (count + p > total_size) { 393 - if (!err) 394 - err = -ENOSPC; 395 - 396 - count = total_size - p; 397 - } 398 - 399 - dst = (void *)(info->screen_base + p); 400 - 401 - if (copy_from_user(dst, buf, count)) 402 - err = -EFAULT; 403 - 404 - if (!err) 405 - *ppos += count; 406 - 407 - par->update_all(par); 408 - 409 - return (err) ? err : count; 410 - } 411 - 412 - static void auok190xfb_fillrect(struct fb_info *info, 413 - const struct fb_fillrect *rect) 414 - { 415 - struct auok190xfb_par *par = info->par; 416 - 417 - sys_fillrect(info, rect); 418 - 419 - par->update_all(par); 420 - } 421 - 422 - static void auok190xfb_copyarea(struct fb_info *info, 423 - const struct fb_copyarea *area) 424 - { 425 - struct auok190xfb_par *par = info->par; 426 - 427 - sys_copyarea(info, area); 428 - 429 - par->update_all(par); 430 - } 431 - 432 - static void auok190xfb_imageblit(struct fb_info *info, 433 - const struct fb_image *image) 434 - { 435 - struct auok190xfb_par *par = info->par; 436 - 437 - sys_imageblit(info, image); 438 - 439 - par->update_all(par); 440 - } 441 - 442 - static int auok190xfb_check_var(struct fb_var_screeninfo *var, 443 - struct fb_info *info) 444 - { 445 - struct device *dev = info->device; 446 - struct auok190xfb_par *par = info->par; 447 - struct panel_info *panel = &panel_table[par->resolution]; 448 - int size; 449 - 450 - /* 451 - * Color depth 452 - */ 453 - 454 - if (var->bits_per_pixel == 8 && var->grayscale == 1) { 455 - /* 456 - * For 8-bit grayscale, R, G, and B offset are equal. 457 - */ 458 - var->red.length = 8; 459 - var->red.offset = 0; 460 - var->red.msb_right = 0; 461 - 462 - var->green.length = 8; 463 - var->green.offset = 0; 464 - var->green.msb_right = 0; 465 - 466 - var->blue.length = 8; 467 - var->blue.offset = 0; 468 - var->blue.msb_right = 0; 469 - 470 - var->transp.length = 0; 471 - var->transp.offset = 0; 472 - var->transp.msb_right = 0; 473 - } else if (var->bits_per_pixel == 16) { 474 - var->red.length = 5; 475 - var->red.offset = 11; 476 - var->red.msb_right = 0; 477 - 478 - var->green.length = 6; 479 - var->green.offset = 5; 480 - var->green.msb_right = 0; 481 - 482 - var->blue.length = 5; 483 - var->blue.offset = 0; 484 - var->blue.msb_right = 0; 485 - 486 - var->transp.length = 0; 487 - var->transp.offset = 0; 488 - var->transp.msb_right = 0; 489 - } else { 490 - dev_warn(dev, "unsupported color mode (bits: %d, grayscale: %d)\n", 491 - info->var.bits_per_pixel, info->var.grayscale); 492 - return -EINVAL; 493 - } 494 - 495 - /* 496 - * Dimensions 497 - */ 498 - 499 - switch (var->rotate) { 500 - case FB_ROTATE_UR: 501 - case FB_ROTATE_UD: 502 - var->xres = panel->w; 503 - var->yres = panel->h; 504 - break; 505 - case FB_ROTATE_CW: 506 - case FB_ROTATE_CCW: 507 - var->xres = panel->h; 508 - var->yres = panel->w; 509 - break; 510 - default: 511 - dev_dbg(dev, "Invalid rotation request\n"); 512 - return -EINVAL; 513 - } 514 - 515 - var->xres_virtual = var->xres; 516 - var->yres_virtual = var->yres; 517 - 518 - /* 519 - * Memory limit 520 - */ 521 - 522 - size = var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8; 523 - if (size > info->fix.smem_len) { 524 - dev_err(dev, "Memory limit exceeded, requested %dK\n", 525 - size >> 10); 526 - return -ENOMEM; 527 - } 528 - 529 - return 0; 530 - } 531 - 532 - static int auok190xfb_set_fix(struct fb_info *info) 533 - { 534 - struct fb_fix_screeninfo *fix = &info->fix; 535 - struct fb_var_screeninfo *var = &info->var; 536 - 537 - fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; 538 - 539 - fix->type = FB_TYPE_PACKED_PIXELS; 540 - fix->accel = FB_ACCEL_NONE; 541 - fix->visual = (var->grayscale) ? FB_VISUAL_STATIC_PSEUDOCOLOR 542 - : FB_VISUAL_TRUECOLOR; 543 - fix->xpanstep = 0; 544 - fix->ypanstep = 0; 545 - fix->ywrapstep = 0; 546 - 547 - return 0; 548 - } 549 - 550 - static int auok190xfb_set_par(struct fb_info *info) 551 - { 552 - struct auok190xfb_par *par = info->par; 553 - 554 - par->rotation = info->var.rotate; 555 - auok190xfb_set_fix(info); 556 - 557 - /* reinit the controller to honor the rotation */ 558 - par->init(par); 559 - 560 - /* wait for init to complete */ 561 - par->board->wait_for_rdy(par); 562 - 563 - return 0; 564 - } 565 - 566 - static struct fb_ops auok190xfb_ops = { 567 - .owner = THIS_MODULE, 568 - .fb_read = fb_sys_read, 569 - .fb_write = auok190xfb_write, 570 - .fb_fillrect = auok190xfb_fillrect, 571 - .fb_copyarea = auok190xfb_copyarea, 572 - .fb_imageblit = auok190xfb_imageblit, 573 - .fb_check_var = auok190xfb_check_var, 574 - .fb_set_par = auok190xfb_set_par, 575 - }; 576 - 577 - /* 578 - * Controller-functions common to both K1900 and K1901 579 - */ 580 - 581 - static int auok190x_read_temperature(struct auok190xfb_par *par) 582 - { 583 - struct device *dev = par->info->device; 584 - u16 data[4]; 585 - int temp; 586 - 587 - pm_runtime_get_sync(dev); 588 - 589 - mutex_lock(&(par->io_lock)); 590 - 591 - auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data); 592 - 593 - mutex_unlock(&(par->io_lock)); 594 - 595 - pm_runtime_mark_last_busy(dev); 596 - pm_runtime_put_autosuspend(dev); 597 - 598 - /* sanitize and split of half-degrees for now */ 599 - temp = ((data[0] & AUOK190X_VERSION_TEMP_MASK) >> 1); 600 - 601 - /* handle positive and negative temperatures */ 602 - if (temp >= 201) 603 - return (255 - temp + 1) * (-1); 604 - else 605 - return temp; 606 - } 607 - 608 - static void auok190x_identify(struct auok190xfb_par *par) 609 - { 610 - struct device *dev = par->info->device; 611 - u16 data[4]; 612 - 613 - pm_runtime_get_sync(dev); 614 - 615 - mutex_lock(&(par->io_lock)); 616 - 617 - auok190x_read_cmdargs(par, AUOK190X_CMD_READ_VERSION, 4, data); 618 - 619 - mutex_unlock(&(par->io_lock)); 620 - 621 - par->epd_type = data[1] & AUOK190X_VERSION_TEMP_MASK; 622 - 623 - par->panel_size_int = AUOK190X_VERSION_SIZE_INT(data[2]); 624 - par->panel_size_float = AUOK190X_VERSION_SIZE_FLOAT(data[2]); 625 - par->panel_model = AUOK190X_VERSION_MODEL(data[2]); 626 - 627 - par->tcon_version = AUOK190X_VERSION_TCON(data[3]); 628 - par->lut_version = AUOK190X_VERSION_LUT(data[3]); 629 - 630 - dev_dbg(dev, "panel %d.%din, model 0x%x, EPD 0x%x TCON-rev 0x%x, LUT-rev 0x%x", 631 - par->panel_size_int, par->panel_size_float, par->panel_model, 632 - par->epd_type, par->tcon_version, par->lut_version); 633 - 634 - pm_runtime_mark_last_busy(dev); 635 - pm_runtime_put_autosuspend(dev); 636 - } 637 - 638 - /* 639 - * Sysfs functions 640 - */ 641 - 642 - static ssize_t update_mode_show(struct device *dev, 643 - struct device_attribute *attr, char *buf) 644 - { 645 - struct fb_info *info = dev_get_drvdata(dev); 646 - struct auok190xfb_par *par = info->par; 647 - 648 - return sprintf(buf, "%d\n", par->update_mode); 649 - } 650 - 651 - static ssize_t update_mode_store(struct device *dev, 652 - struct device_attribute *attr, 653 - const char *buf, size_t count) 654 - { 655 - struct fb_info *info = dev_get_drvdata(dev); 656 - struct auok190xfb_par *par = info->par; 657 - int mode, ret; 658 - 659 - ret = kstrtoint(buf, 10, &mode); 660 - if (ret) 661 - return ret; 662 - 663 - par->update_mode = mode; 664 - 665 - /* if we enter a better mode, do a full update */ 666 - if (par->last_mode > 1 && mode < par->last_mode) 667 - par->update_all(par); 668 - 669 - return count; 670 - } 671 - 672 - static ssize_t flash_show(struct device *dev, struct device_attribute *attr, 673 - char *buf) 674 - { 675 - struct fb_info *info = dev_get_drvdata(dev); 676 - struct auok190xfb_par *par = info->par; 677 - 678 - return sprintf(buf, "%d\n", par->flash); 679 - } 680 - 681 - static ssize_t flash_store(struct device *dev, struct device_attribute *attr, 682 - const char *buf, size_t count) 683 - { 684 - struct fb_info *info = dev_get_drvdata(dev); 685 - struct auok190xfb_par *par = info->par; 686 - int flash, ret; 687 - 688 - ret = kstrtoint(buf, 10, &flash); 689 - if (ret) 690 - return ret; 691 - 692 - if (flash > 0) 693 - par->flash = 1; 694 - else 695 - par->flash = 0; 696 - 697 - return count; 698 - } 699 - 700 - static ssize_t temp_show(struct device *dev, struct device_attribute *attr, 701 - char *buf) 702 - { 703 - struct fb_info *info = dev_get_drvdata(dev); 704 - struct auok190xfb_par *par = info->par; 705 - int temp; 706 - 707 - temp = auok190x_read_temperature(par); 708 - return sprintf(buf, "%d\n", temp); 709 - } 710 - 711 - static DEVICE_ATTR_RW(update_mode); 712 - static DEVICE_ATTR_RW(flash); 713 - static DEVICE_ATTR(temp, 0644, temp_show, NULL); 714 - 715 - static struct attribute *auok190x_attributes[] = { 716 - &dev_attr_update_mode.attr, 717 - &dev_attr_flash.attr, 718 - &dev_attr_temp.attr, 719 - NULL 720 - }; 721 - 722 - static const struct attribute_group auok190x_attr_group = { 723 - .attrs = auok190x_attributes, 724 - }; 725 - 726 - static int auok190x_power(struct auok190xfb_par *par, bool on) 727 - { 728 - struct auok190x_board *board = par->board; 729 - int ret; 730 - 731 - if (on) { 732 - /* We should maintain POWER up for at least 80ms before set 733 - * RST_N and SLP_N to high (TCON spec 20100803_v35 p59) 734 - */ 735 - ret = regulator_enable(par->regulator); 736 - if (ret) 737 - return ret; 738 - 739 - msleep(200); 740 - gpio_set_value(board->gpio_nrst, 1); 741 - gpio_set_value(board->gpio_nsleep, 1); 742 - msleep(200); 743 - } else { 744 - regulator_disable(par->regulator); 745 - gpio_set_value(board->gpio_nrst, 0); 746 - gpio_set_value(board->gpio_nsleep, 0); 747 - } 748 - 749 - return 0; 750 - } 751 - 752 - /* 753 - * Recovery - powercycle the controller 754 - */ 755 - 756 - static void auok190x_recover(struct auok190xfb_par *par) 757 - { 758 - struct device *dev = par->info->device; 759 - 760 - auok190x_power(par, 0); 761 - msleep(100); 762 - auok190x_power(par, 1); 763 - 764 - /* after powercycling the device, it's always active */ 765 - pm_runtime_set_active(dev); 766 - par->standby = 0; 767 - 768 - par->init(par); 769 - 770 - /* wait for init to complete */ 771 - par->board->wait_for_rdy(par); 772 - } 773 - 774 - /* 775 - * Power-management 776 - */ 777 - static int __maybe_unused auok190x_runtime_suspend(struct device *dev) 778 - { 779 - struct fb_info *info = dev_get_drvdata(dev); 780 - struct auok190xfb_par *par = info->par; 781 - struct auok190x_board *board = par->board; 782 - u16 standby_param; 783 - 784 - /* take and keep the lock until we are resumed, as the controller 785 - * will never reach the non-busy state when in standby mode 786 - */ 787 - mutex_lock(&(par->io_lock)); 788 - 789 - if (par->standby) { 790 - dev_warn(dev, "already in standby, runtime-pm pairing mismatch\n"); 791 - mutex_unlock(&(par->io_lock)); 792 - return 0; 793 - } 794 - 795 - /* according to runtime_pm.txt runtime_suspend only means, that the 796 - * device will not process data and will not communicate with the CPU 797 - * As we hold the lock, this stays true even without standby 798 - */ 799 - if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 800 - dev_dbg(dev, "runtime suspend without standby\n"); 801 - goto finish; 802 - } else if (board->quirks & AUOK190X_QUIRK_STANDBYPARAM) { 803 - /* for some TCON versions STANDBY expects a parameter (0) but 804 - * it seems the real tcon version has to be determined yet. 805 - */ 806 - dev_dbg(dev, "runtime suspend with additional empty param\n"); 807 - standby_param = 0; 808 - auok190x_send_cmdargs(par, AUOK190X_CMD_STANDBY, 1, 809 - &standby_param); 810 - } else { 811 - dev_dbg(dev, "runtime suspend without param\n"); 812 - auok190x_send_command(par, AUOK190X_CMD_STANDBY); 813 - } 814 - 815 - msleep(64); 816 - 817 - finish: 818 - par->standby = 1; 819 - 820 - return 0; 821 - } 822 - 823 - static int __maybe_unused auok190x_runtime_resume(struct device *dev) 824 - { 825 - struct fb_info *info = dev_get_drvdata(dev); 826 - struct auok190xfb_par *par = info->par; 827 - struct auok190x_board *board = par->board; 828 - 829 - if (!par->standby) { 830 - dev_warn(dev, "not in standby, runtime-pm pairing mismatch\n"); 831 - return 0; 832 - } 833 - 834 - if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 835 - dev_dbg(dev, "runtime resume without standby\n"); 836 - } else { 837 - /* when in standby, controller is always busy 838 - * and only accepts the wakeup command 839 - */ 840 - dev_dbg(dev, "runtime resume from standby\n"); 841 - auok190x_send_command_nowait(par, AUOK190X_CMD_WAKEUP); 842 - 843 - msleep(160); 844 - 845 - /* wait for the controller to be ready and release the lock */ 846 - board->wait_for_rdy(par); 847 - } 848 - 849 - par->standby = 0; 850 - 851 - mutex_unlock(&(par->io_lock)); 852 - 853 - return 0; 854 - } 855 - 856 - static int __maybe_unused auok190x_suspend(struct device *dev) 857 - { 858 - struct fb_info *info = dev_get_drvdata(dev); 859 - struct auok190xfb_par *par = info->par; 860 - struct auok190x_board *board = par->board; 861 - int ret; 862 - 863 - dev_dbg(dev, "suspend\n"); 864 - if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 865 - /* suspend via powering off the ic */ 866 - dev_dbg(dev, "suspend with broken standby\n"); 867 - 868 - auok190x_power(par, 0); 869 - } else { 870 - dev_dbg(dev, "suspend using sleep\n"); 871 - 872 - /* the sleep state can only be entered from the standby state. 873 - * pm_runtime_get_noresume gets called before the suspend call. 874 - * So the devices usage count is >0 but it is not necessarily 875 - * active. 876 - */ 877 - if (!pm_runtime_status_suspended(dev)) { 878 - ret = auok190x_runtime_suspend(dev); 879 - if (ret < 0) { 880 - dev_err(dev, "auok190x_runtime_suspend failed with %d\n", 881 - ret); 882 - return ret; 883 - } 884 - par->manual_standby = 1; 885 - } 886 - 887 - gpio_direction_output(board->gpio_nsleep, 0); 888 - } 889 - 890 - msleep(100); 891 - 892 - return 0; 893 - } 894 - 895 - static int __maybe_unused auok190x_resume(struct device *dev) 896 - { 897 - struct fb_info *info = dev_get_drvdata(dev); 898 - struct auok190xfb_par *par = info->par; 899 - struct auok190x_board *board = par->board; 900 - 901 - dev_dbg(dev, "resume\n"); 902 - if (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) { 903 - dev_dbg(dev, "resume with broken standby\n"); 904 - 905 - auok190x_power(par, 1); 906 - 907 - par->init(par); 908 - } else { 909 - dev_dbg(dev, "resume from sleep\n"); 910 - 911 - /* device should be in runtime suspend when we were suspended 912 - * and pm_runtime_put_sync gets called after this function. 913 - * So there is no need to touch the standby mode here at all. 914 - */ 915 - gpio_direction_output(board->gpio_nsleep, 1); 916 - msleep(100); 917 - 918 - /* an additional init call seems to be necessary after sleep */ 919 - auok190x_runtime_resume(dev); 920 - par->init(par); 921 - 922 - /* if we were runtime-suspended before, suspend again*/ 923 - if (!par->manual_standby) 924 - auok190x_runtime_suspend(dev); 925 - else 926 - par->manual_standby = 0; 927 - } 928 - 929 - return 0; 930 - } 931 - 932 - const struct dev_pm_ops auok190x_pm = { 933 - SET_RUNTIME_PM_OPS(auok190x_runtime_suspend, auok190x_runtime_resume, 934 - NULL) 935 - SET_SYSTEM_SLEEP_PM_OPS(auok190x_suspend, auok190x_resume) 936 - }; 937 - EXPORT_SYMBOL_GPL(auok190x_pm); 938 - 939 - /* 940 - * Common probe and remove code 941 - */ 942 - 943 - int auok190x_common_probe(struct platform_device *pdev, 944 - struct auok190x_init_data *init) 945 - { 946 - struct auok190x_board *board = init->board; 947 - struct auok190xfb_par *par; 948 - struct fb_info *info; 949 - struct panel_info *panel; 950 - int videomemorysize, ret; 951 - unsigned char *videomemory; 952 - 953 - /* check board contents */ 954 - if (!board->init || !board->cleanup || !board->wait_for_rdy 955 - || !board->set_ctl || !board->set_hdb || !board->get_hdb 956 - || !board->setup_irq) 957 - return -EINVAL; 958 - 959 - info = framebuffer_alloc(sizeof(struct auok190xfb_par), &pdev->dev); 960 - if (!info) 961 - return -ENOMEM; 962 - 963 - par = info->par; 964 - par->info = info; 965 - par->board = board; 966 - par->recover = auok190x_recover; 967 - par->update_partial = init->update_partial; 968 - par->update_all = init->update_all; 969 - par->need_refresh = init->need_refresh; 970 - par->init = init->init; 971 - 972 - /* init update modes */ 973 - par->update_cnt = 0; 974 - par->update_mode = -1; 975 - par->last_mode = -1; 976 - par->flash = 0; 977 - 978 - par->regulator = regulator_get(info->device, "vdd"); 979 - if (IS_ERR(par->regulator)) { 980 - ret = PTR_ERR(par->regulator); 981 - dev_err(info->device, "Failed to get regulator: %d\n", ret); 982 - goto err_reg; 983 - } 984 - 985 - ret = board->init(par); 986 - if (ret) { 987 - dev_err(info->device, "board init failed, %d\n", ret); 988 - goto err_board; 989 - } 990 - 991 - ret = gpio_request(board->gpio_nsleep, "AUOK190x sleep"); 992 - if (ret) { 993 - dev_err(info->device, "could not request sleep gpio, %d\n", 994 - ret); 995 - goto err_gpio1; 996 - } 997 - 998 - ret = gpio_direction_output(board->gpio_nsleep, 0); 999 - if (ret) { 1000 - dev_err(info->device, "could not set sleep gpio, %d\n", ret); 1001 - goto err_gpio2; 1002 - } 1003 - 1004 - ret = gpio_request(board->gpio_nrst, "AUOK190x reset"); 1005 - if (ret) { 1006 - dev_err(info->device, "could not request reset gpio, %d\n", 1007 - ret); 1008 - goto err_gpio2; 1009 - } 1010 - 1011 - ret = gpio_direction_output(board->gpio_nrst, 0); 1012 - if (ret) { 1013 - dev_err(info->device, "could not set reset gpio, %d\n", ret); 1014 - goto err_gpio3; 1015 - } 1016 - 1017 - ret = auok190x_power(par, 1); 1018 - if (ret) { 1019 - dev_err(info->device, "could not power on the device, %d\n", 1020 - ret); 1021 - goto err_gpio3; 1022 - } 1023 - 1024 - mutex_init(&par->io_lock); 1025 - 1026 - init_waitqueue_head(&par->waitq); 1027 - 1028 - ret = par->board->setup_irq(par->info); 1029 - if (ret) { 1030 - dev_err(info->device, "could not setup ready-irq, %d\n", ret); 1031 - goto err_irq; 1032 - } 1033 - 1034 - /* wait for init to complete */ 1035 - par->board->wait_for_rdy(par); 1036 - 1037 - /* 1038 - * From here on the controller can talk to us 1039 - */ 1040 - 1041 - /* initialise fix, var, resolution and rotation */ 1042 - 1043 - strlcpy(info->fix.id, init->id, 16); 1044 - info->var.bits_per_pixel = 8; 1045 - info->var.grayscale = 1; 1046 - 1047 - panel = &panel_table[board->resolution]; 1048 - 1049 - par->resolution = board->resolution; 1050 - par->rotation = 0; 1051 - 1052 - /* videomemory handling */ 1053 - 1054 - videomemorysize = roundup((panel->w * panel->h) * 2, PAGE_SIZE); 1055 - videomemory = vzalloc(videomemorysize); 1056 - if (!videomemory) { 1057 - ret = -ENOMEM; 1058 - goto err_irq; 1059 - } 1060 - 1061 - info->screen_base = (char *)videomemory; 1062 - info->fix.smem_len = videomemorysize; 1063 - 1064 - info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; 1065 - info->fbops = &auok190xfb_ops; 1066 - 1067 - ret = auok190xfb_check_var(&info->var, info); 1068 - if (ret) 1069 - goto err_defio; 1070 - 1071 - auok190xfb_set_fix(info); 1072 - 1073 - /* deferred io init */ 1074 - 1075 - info->fbdefio = devm_kzalloc(info->device, 1076 - sizeof(struct fb_deferred_io), 1077 - GFP_KERNEL); 1078 - if (!info->fbdefio) { 1079 - ret = -ENOMEM; 1080 - goto err_defio; 1081 - } 1082 - 1083 - dev_dbg(info->device, "targeting %d frames per second\n", board->fps); 1084 - info->fbdefio->delay = HZ / board->fps; 1085 - info->fbdefio->first_io = auok190xfb_dpy_first_io, 1086 - info->fbdefio->deferred_io = auok190xfb_dpy_deferred_io, 1087 - fb_deferred_io_init(info); 1088 - 1089 - /* color map */ 1090 - 1091 - ret = fb_alloc_cmap(&info->cmap, 256, 0); 1092 - if (ret < 0) { 1093 - dev_err(info->device, "Failed to allocate colormap\n"); 1094 - goto err_cmap; 1095 - } 1096 - 1097 - /* controller init */ 1098 - 1099 - par->consecutive_threshold = 100; 1100 - par->init(par); 1101 - auok190x_identify(par); 1102 - 1103 - platform_set_drvdata(pdev, info); 1104 - 1105 - ret = register_framebuffer(info); 1106 - if (ret < 0) 1107 - goto err_regfb; 1108 - 1109 - ret = sysfs_create_group(&info->device->kobj, &auok190x_attr_group); 1110 - if (ret) 1111 - goto err_sysfs; 1112 - 1113 - dev_info(info->device, "fb%d: %dx%d using %dK of video memory\n", 1114 - info->node, info->var.xres, info->var.yres, 1115 - videomemorysize >> 10); 1116 - 1117 - /* increase autosuspend_delay when we use alternative methods 1118 - * for runtime_pm 1119 - */ 1120 - par->autosuspend_delay = (board->quirks & AUOK190X_QUIRK_STANDBYBROKEN) 1121 - ? 1000 : 200; 1122 - 1123 - pm_runtime_set_active(info->device); 1124 - pm_runtime_enable(info->device); 1125 - pm_runtime_set_autosuspend_delay(info->device, par->autosuspend_delay); 1126 - pm_runtime_use_autosuspend(info->device); 1127 - 1128 - return 0; 1129 - 1130 - err_sysfs: 1131 - unregister_framebuffer(info); 1132 - err_regfb: 1133 - fb_dealloc_cmap(&info->cmap); 1134 - err_cmap: 1135 - fb_deferred_io_cleanup(info); 1136 - err_defio: 1137 - vfree((void *)info->screen_base); 1138 - err_irq: 1139 - auok190x_power(par, 0); 1140 - err_gpio3: 1141 - gpio_free(board->gpio_nrst); 1142 - err_gpio2: 1143 - gpio_free(board->gpio_nsleep); 1144 - err_gpio1: 1145 - board->cleanup(par); 1146 - err_board: 1147 - regulator_put(par->regulator); 1148 - err_reg: 1149 - framebuffer_release(info); 1150 - 1151 - return ret; 1152 - } 1153 - EXPORT_SYMBOL_GPL(auok190x_common_probe); 1154 - 1155 - int auok190x_common_remove(struct platform_device *pdev) 1156 - { 1157 - struct fb_info *info = platform_get_drvdata(pdev); 1158 - struct auok190xfb_par *par = info->par; 1159 - struct auok190x_board *board = par->board; 1160 - 1161 - pm_runtime_disable(info->device); 1162 - 1163 - sysfs_remove_group(&info->device->kobj, &auok190x_attr_group); 1164 - 1165 - unregister_framebuffer(info); 1166 - 1167 - fb_dealloc_cmap(&info->cmap); 1168 - 1169 - fb_deferred_io_cleanup(info); 1170 - 1171 - vfree((void *)info->screen_base); 1172 - 1173 - auok190x_power(par, 0); 1174 - 1175 - gpio_free(board->gpio_nrst); 1176 - gpio_free(board->gpio_nsleep); 1177 - 1178 - board->cleanup(par); 1179 - 1180 - regulator_put(par->regulator); 1181 - 1182 - framebuffer_release(info); 1183 - 1184 - return 0; 1185 - } 1186 - EXPORT_SYMBOL_GPL(auok190x_common_remove); 1187 - 1188 - MODULE_DESCRIPTION("Common code for AUO-K190X controllers"); 1189 - MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); 1190 - MODULE_LICENSE("GPL");
-129
drivers/video/fbdev/auo_k190x.h
··· 1 - /* 2 - * Private common definitions 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 - 11 - /* 12 - * I80 interface specific defines 13 - */ 14 - 15 - #define AUOK190X_I80_CS 0x01 16 - #define AUOK190X_I80_DC 0x02 17 - #define AUOK190X_I80_WR 0x03 18 - #define AUOK190X_I80_OE 0x04 19 - 20 - /* 21 - * AUOK190x commands, common to both controllers 22 - */ 23 - 24 - #define AUOK190X_CMD_INIT 0x0000 25 - #define AUOK190X_CMD_STANDBY 0x0001 26 - #define AUOK190X_CMD_WAKEUP 0x0002 27 - #define AUOK190X_CMD_TCON_RESET 0x0003 28 - #define AUOK190X_CMD_DATA_STOP 0x1002 29 - #define AUOK190X_CMD_LUT_START 0x1003 30 - #define AUOK190X_CMD_DISP_REFRESH 0x1004 31 - #define AUOK190X_CMD_DISP_RESET 0x1005 32 - #define AUOK190X_CMD_PRE_DISPLAY_START 0x100D 33 - #define AUOK190X_CMD_PRE_DISPLAY_STOP 0x100F 34 - #define AUOK190X_CMD_FLASH_W 0x2000 35 - #define AUOK190X_CMD_FLASH_E 0x2001 36 - #define AUOK190X_CMD_FLASH_STS 0x2002 37 - #define AUOK190X_CMD_FRAMERATE 0x3000 38 - #define AUOK190X_CMD_READ_VERSION 0x4000 39 - #define AUOK190X_CMD_READ_STATUS 0x4001 40 - #define AUOK190X_CMD_READ_LUT 0x4003 41 - #define AUOK190X_CMD_DRIVERTIMING 0x5000 42 - #define AUOK190X_CMD_LBALANCE 0x5001 43 - #define AUOK190X_CMD_AGINGMODE 0x6000 44 - #define AUOK190X_CMD_AGINGEXIT 0x6001 45 - 46 - /* 47 - * Common settings for AUOK190X_CMD_INIT 48 - */ 49 - 50 - #define AUOK190X_INIT_DATA_FILTER (0 << 12) 51 - #define AUOK190X_INIT_DATA_BYPASS (1 << 12) 52 - #define AUOK190X_INIT_INVERSE_WHITE (0 << 9) 53 - #define AUOK190X_INIT_INVERSE_BLACK (1 << 9) 54 - #define AUOK190X_INIT_SCAN_DOWN (0 << 1) 55 - #define AUOK190X_INIT_SCAN_UP (1 << 1) 56 - #define AUOK190X_INIT_SHIFT_LEFT (0 << 0) 57 - #define AUOK190X_INIT_SHIFT_RIGHT (1 << 0) 58 - 59 - /* Common bits to pixels 60 - * Mode 15-12 11-8 7-4 3-0 61 - * format0 4 3 2 1 62 - * format1 3 4 1 2 63 - */ 64 - 65 - #define AUOK190X_INIT_FORMAT0 0 66 - #define AUOK190X_INIT_FORMAT1 (1 << 6) 67 - 68 - /* 69 - * settings for AUOK190X_CMD_RESET 70 - */ 71 - 72 - #define AUOK190X_RESET_TCON (0 << 0) 73 - #define AUOK190X_RESET_NORMAL (1 << 0) 74 - #define AUOK190X_RESET_PON (1 << 1) 75 - 76 - /* 77 - * AUOK190X_CMD_VERSION 78 - */ 79 - 80 - #define AUOK190X_VERSION_TEMP_MASK (0x1ff) 81 - #define AUOK190X_VERSION_EPD_MASK (0xff) 82 - #define AUOK190X_VERSION_SIZE_INT(_val) ((_val & 0xfc00) >> 10) 83 - #define AUOK190X_VERSION_SIZE_FLOAT(_val) ((_val & 0x3c0) >> 6) 84 - #define AUOK190X_VERSION_MODEL(_val) (_val & 0x3f) 85 - #define AUOK190X_VERSION_LUT(_val) (_val & 0xff) 86 - #define AUOK190X_VERSION_TCON(_val) ((_val & 0xff00) >> 8) 87 - 88 - /* 89 - * update modes for CMD_PARTIALDISP on K1900 and CMD_DDMA on K1901 90 - */ 91 - 92 - #define AUOK190X_UPDATE_MODE(_res) ((_res & 0x7) << 12) 93 - #define AUOK190X_UPDATE_NONFLASH (1 << 15) 94 - 95 - /* 96 - * track panel specific parameters for common init 97 - */ 98 - 99 - struct auok190x_init_data { 100 - char *id; 101 - struct auok190x_board *board; 102 - 103 - void (*update_partial)(struct auok190xfb_par *par, u16 y1, u16 y2); 104 - void (*update_all)(struct auok190xfb_par *par); 105 - bool (*need_refresh)(struct auok190xfb_par *par); 106 - void (*init)(struct auok190xfb_par *par); 107 - }; 108 - 109 - 110 - extern void auok190x_send_command_nowait(struct auok190xfb_par *par, u16 data); 111 - extern int auok190x_send_command(struct auok190xfb_par *par, u16 data); 112 - extern void auok190x_send_cmdargs_nowait(struct auok190xfb_par *par, u16 cmd, 113 - int argc, u16 *argv); 114 - extern int auok190x_send_cmdargs(struct auok190xfb_par *par, u16 cmd, 115 - int argc, u16 *argv); 116 - extern void auok190x_send_cmdargs_pixels_nowait(struct auok190xfb_par *par, 117 - u16 cmd, int argc, u16 *argv, 118 - int size, u16 *data); 119 - extern int auok190x_send_cmdargs_pixels(struct auok190xfb_par *par, u16 cmd, 120 - int argc, u16 *argv, int size, 121 - u16 *data); 122 - extern int auok190x_read_cmdargs(struct auok190xfb_par *par, u16 cmd, 123 - int argc, u16 *argv); 124 - 125 - extern int auok190x_common_probe(struct platform_device *pdev, 126 - struct auok190x_init_data *init); 127 - extern int auok190x_common_remove(struct platform_device *pdev); 128 - 129 - extern const struct dev_pm_ops auok190x_pm;
-107
include/video/auo_k190xfb.h
··· 1 - /* 2 - * Definitions 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 - 11 - #ifndef _LINUX_VIDEO_AUO_K190XFB_H_ 12 - #define _LINUX_VIDEO_AUO_K190XFB_H_ 13 - 14 - /* Controller standby command needs a param */ 15 - #define AUOK190X_QUIRK_STANDBYPARAM (1 << 0) 16 - 17 - /* Controller standby is completely broken */ 18 - #define AUOK190X_QUIRK_STANDBYBROKEN (1 << 1) 19 - 20 - /* 21 - * Resolutions for the displays 22 - */ 23 - #define AUOK190X_RESOLUTION_800_600 0 24 - #define AUOK190X_RESOLUTION_1024_768 1 25 - #define AUOK190X_RESOLUTION_600_800 4 26 - #define AUOK190X_RESOLUTION_768_1024 5 27 - 28 - /* 29 - * struct used by auok190x. board specific stuff comes from *board 30 - */ 31 - struct auok190xfb_par { 32 - struct fb_info *info; 33 - struct auok190x_board *board; 34 - 35 - struct regulator *regulator; 36 - 37 - struct mutex io_lock; 38 - struct delayed_work work; 39 - wait_queue_head_t waitq; 40 - int resolution; 41 - int rotation; 42 - int consecutive_threshold; 43 - int update_cnt; 44 - 45 - /* panel and controller informations */ 46 - int epd_type; 47 - int panel_size_int; 48 - int panel_size_float; 49 - int panel_model; 50 - int tcon_version; 51 - int lut_version; 52 - 53 - /* individual controller callbacks */ 54 - void (*update_partial)(struct auok190xfb_par *par, u16 y1, u16 y2); 55 - void (*update_all)(struct auok190xfb_par *par); 56 - bool (*need_refresh)(struct auok190xfb_par *par); 57 - void (*init)(struct auok190xfb_par *par); 58 - void (*recover)(struct auok190xfb_par *par); 59 - 60 - int update_mode; /* mode to use for updates */ 61 - int last_mode; /* update mode last used */ 62 - int flash; 63 - 64 - /* power management */ 65 - int autosuspend_delay; 66 - bool standby; 67 - bool manual_standby; 68 - }; 69 - 70 - /** 71 - * Board specific platform-data 72 - * @init: initialize the controller interface 73 - * @cleanup: cleanup the controller interface 74 - * @wait_for_rdy: wait until the controller is not busy anymore 75 - * @set_ctl: change an interface control 76 - * @set_hdb: write a value to the data register 77 - * @get_hdb: read a value from the data register 78 - * @setup_irq: method to setup the irq handling on the busy gpio 79 - * @gpio_nsleep: sleep gpio 80 - * @gpio_nrst: reset gpio 81 - * @gpio_nbusy: busy gpio 82 - * @resolution: one of the AUOK190X_RESOLUTION constants 83 - * @rotation: rotation of the framebuffer 84 - * @quirks: controller quirks to honor 85 - * @fps: frames per second for defio 86 - */ 87 - struct auok190x_board { 88 - int (*init)(struct auok190xfb_par *); 89 - void (*cleanup)(struct auok190xfb_par *); 90 - int (*wait_for_rdy)(struct auok190xfb_par *); 91 - 92 - void (*set_ctl)(struct auok190xfb_par *, unsigned char, u8); 93 - void (*set_hdb)(struct auok190xfb_par *, u16); 94 - u16 (*get_hdb)(struct auok190xfb_par *); 95 - 96 - int (*setup_irq)(struct fb_info *); 97 - 98 - int gpio_nsleep; 99 - int gpio_nrst; 100 - int gpio_nbusy; 101 - 102 - int resolution; 103 - int quirks; 104 - int fps; 105 - }; 106 - 107 - #endif