Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /***************************************************************************
0003  *   Copyright (C) 2010-2012 by Bruno Prémont <bonbons@linux-vserver.org>  *
0004  *                                                                         *
0005  *   Based on Logitech G13 driver (v0.4)                                   *
0006  *     Copyright (C) 2009 by Rick L. Vinyard, Jr. <rvinyard@cs.nmsu.edu>   *
0007  *                                                                         *
0008  ***************************************************************************/
0009 
0010 #define PICOLCD_NAME "PicoLCD (graphic)"
0011 
0012 /* Report numbers */
0013 #define REPORT_ERROR_CODE      0x10 /* LCD: IN[16]  */
0014 #define   ERR_SUCCESS            0x00
0015 #define   ERR_PARAMETER_MISSING  0x01
0016 #define   ERR_DATA_MISSING       0x02
0017 #define   ERR_BLOCK_READ_ONLY    0x03
0018 #define   ERR_BLOCK_NOT_ERASABLE 0x04
0019 #define   ERR_BLOCK_TOO_BIG      0x05
0020 #define   ERR_SECTION_OVERFLOW   0x06
0021 #define   ERR_INVALID_CMD_LEN    0x07
0022 #define   ERR_INVALID_DATA_LEN   0x08
0023 #define REPORT_KEY_STATE       0x11 /* LCD: IN[2]   */
0024 #define REPORT_IR_DATA         0x21 /* LCD: IN[63]  */
0025 #define REPORT_EE_DATA         0x32 /* LCD: IN[63]  */
0026 #define REPORT_MEMORY          0x41 /* LCD: IN[63]  */
0027 #define REPORT_LED_STATE       0x81 /* LCD: OUT[1]  */
0028 #define REPORT_BRIGHTNESS      0x91 /* LCD: OUT[1]  */
0029 #define REPORT_CONTRAST        0x92 /* LCD: OUT[1]  */
0030 #define REPORT_RESET           0x93 /* LCD: OUT[2]  */
0031 #define REPORT_LCD_CMD         0x94 /* LCD: OUT[63] */
0032 #define REPORT_LCD_DATA        0x95 /* LCD: OUT[63] */
0033 #define REPORT_LCD_CMD_DATA    0x96 /* LCD: OUT[63] */
0034 #define REPORT_EE_READ         0xa3 /* LCD: OUT[63] */
0035 #define REPORT_EE_WRITE        0xa4 /* LCD: OUT[63] */
0036 #define REPORT_ERASE_MEMORY    0xb2 /* LCD: OUT[2]  */
0037 #define REPORT_READ_MEMORY     0xb3 /* LCD: OUT[3]  */
0038 #define REPORT_WRITE_MEMORY    0xb4 /* LCD: OUT[63] */
0039 #define REPORT_SPLASH_RESTART  0xc1 /* LCD: OUT[1]  */
0040 #define REPORT_EXIT_KEYBOARD   0xef /* LCD: OUT[2]  */
0041 #define REPORT_VERSION         0xf1 /* LCD: IN[2],OUT[1]    Bootloader: IN[2],OUT[1]   */
0042 #define REPORT_BL_ERASE_MEMORY 0xf2 /*                      Bootloader: IN[36],OUT[4]  */
0043 #define REPORT_BL_READ_MEMORY  0xf3 /*                      Bootloader: IN[36],OUT[4]  */
0044 #define REPORT_BL_WRITE_MEMORY 0xf4 /*                      Bootloader: IN[36],OUT[36] */
0045 #define REPORT_DEVID           0xf5 /* LCD: IN[5], OUT[1]   Bootloader: IN[5],OUT[1]   */
0046 #define REPORT_SPLASH_SIZE     0xf6 /* LCD: IN[4], OUT[1]   */
0047 #define REPORT_HOOK_VERSION    0xf7 /* LCD: IN[2], OUT[1]   */
0048 #define REPORT_EXIT_FLASHER    0xff /*                      Bootloader: OUT[2]         */
0049 
0050 /* Description of in-progress IO operation, used for operations
0051  * that trigger response from device */
0052 struct picolcd_pending {
0053     struct hid_report *out_report;
0054     struct hid_report *in_report;
0055     struct completion ready;
0056     int raw_size;
0057     u8 raw_data[64];
0058 };
0059 
0060 
0061 #define PICOLCD_KEYS 17
0062 
0063 /* Per device data structure */
0064 struct picolcd_data {
0065     struct hid_device *hdev;
0066 #ifdef CONFIG_DEBUG_FS
0067     struct dentry *debug_reset;
0068     struct dentry *debug_eeprom;
0069     struct dentry *debug_flash;
0070     struct mutex mutex_flash;
0071     int addr_sz;
0072 #endif
0073     u8 version[2];
0074     unsigned short opmode_delay;
0075     /* input stuff */
0076     u8 pressed_keys[2];
0077     struct input_dev *input_keys;
0078 #ifdef CONFIG_HID_PICOLCD_CIR
0079     struct rc_dev *rc_dev;
0080 #endif
0081     unsigned short keycode[PICOLCD_KEYS];
0082 
0083 #ifdef CONFIG_HID_PICOLCD_FB
0084     /* Framebuffer stuff */
0085     struct fb_info *fb_info;
0086 #endif /* CONFIG_HID_PICOLCD_FB */
0087 #ifdef CONFIG_HID_PICOLCD_LCD
0088     struct lcd_device *lcd;
0089     u8 lcd_contrast;
0090 #endif /* CONFIG_HID_PICOLCD_LCD */
0091 #ifdef CONFIG_HID_PICOLCD_BACKLIGHT
0092     struct backlight_device *backlight;
0093     u8 lcd_brightness;
0094     u8 lcd_power;
0095 #endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
0096 #ifdef CONFIG_HID_PICOLCD_LEDS
0097     /* LED stuff */
0098     u8 led_state;
0099     struct led_classdev *led[8];
0100 #endif /* CONFIG_HID_PICOLCD_LEDS */
0101 
0102     /* Housekeeping stuff */
0103     spinlock_t lock;
0104     struct mutex mutex;
0105     struct picolcd_pending *pending;
0106     int status;
0107 #define PICOLCD_BOOTLOADER 1
0108 #define PICOLCD_FAILED 2
0109 #define PICOLCD_CIR_SHUN 4
0110 };
0111 
0112 #ifdef CONFIG_HID_PICOLCD_FB
0113 struct picolcd_fb_data {
0114     /* Framebuffer stuff */
0115     spinlock_t lock;
0116     struct picolcd_data *picolcd;
0117     u8 update_rate;
0118     u8 bpp;
0119     u8 force;
0120     u8 ready;
0121     u8 *vbitmap;        /* local copy of what was sent to PicoLCD */
0122     u8 *bitmap;     /* framebuffer */
0123 };
0124 #endif /* CONFIG_HID_PICOLCD_FB */
0125 
0126 /* Find a given report */
0127 #define picolcd_in_report(id, dev) picolcd_report(id, dev, HID_INPUT_REPORT)
0128 #define picolcd_out_report(id, dev) picolcd_report(id, dev, HID_OUTPUT_REPORT)
0129 
0130 struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir);
0131 
0132 #ifdef CONFIG_DEBUG_FS
0133 void picolcd_debug_out_report(struct picolcd_data *data,
0134         struct hid_device *hdev, struct hid_report *report);
0135 #define hid_hw_request(a, b, c) \
0136     do { \
0137         picolcd_debug_out_report(hid_get_drvdata(a), a, b); \
0138         hid_hw_request(a, b, c); \
0139     } while (0)
0140 
0141 void picolcd_debug_raw_event(struct picolcd_data *data,
0142         struct hid_device *hdev, struct hid_report *report,
0143         u8 *raw_data, int size);
0144 
0145 void picolcd_init_devfs(struct picolcd_data *data,
0146         struct hid_report *eeprom_r, struct hid_report *eeprom_w,
0147         struct hid_report *flash_r, struct hid_report *flash_w,
0148         struct hid_report *reset);
0149 
0150 void picolcd_exit_devfs(struct picolcd_data *data);
0151 #else
0152 static inline void picolcd_debug_out_report(struct picolcd_data *data,
0153         struct hid_device *hdev, struct hid_report *report)
0154 {
0155 }
0156 static inline void picolcd_debug_raw_event(struct picolcd_data *data,
0157         struct hid_device *hdev, struct hid_report *report,
0158         u8 *raw_data, int size)
0159 {
0160 }
0161 static inline void picolcd_init_devfs(struct picolcd_data *data,
0162         struct hid_report *eeprom_r, struct hid_report *eeprom_w,
0163         struct hid_report *flash_r, struct hid_report *flash_w,
0164         struct hid_report *reset)
0165 {
0166 }
0167 static inline void picolcd_exit_devfs(struct picolcd_data *data)
0168 {
0169 }
0170 #endif /* CONFIG_DEBUG_FS */
0171 
0172 
0173 #ifdef CONFIG_HID_PICOLCD_FB
0174 int picolcd_fb_reset(struct picolcd_data *data, int clear);
0175 
0176 int picolcd_init_framebuffer(struct picolcd_data *data);
0177 
0178 void picolcd_exit_framebuffer(struct picolcd_data *data);
0179 
0180 void picolcd_fb_refresh(struct picolcd_data *data);
0181 #define picolcd_fbinfo(d) ((d)->fb_info)
0182 #else
0183 static inline int picolcd_fb_reset(struct picolcd_data *data, int clear)
0184 {
0185     return 0;
0186 }
0187 static inline int picolcd_init_framebuffer(struct picolcd_data *data)
0188 {
0189     return 0;
0190 }
0191 static inline void picolcd_exit_framebuffer(struct picolcd_data *data)
0192 {
0193 }
0194 static inline void picolcd_fb_refresh(struct picolcd_data *data)
0195 {
0196 }
0197 #define picolcd_fbinfo(d) NULL
0198 #endif /* CONFIG_HID_PICOLCD_FB */
0199 
0200 
0201 #ifdef CONFIG_HID_PICOLCD_BACKLIGHT
0202 int picolcd_init_backlight(struct picolcd_data *data,
0203         struct hid_report *report);
0204 
0205 void picolcd_exit_backlight(struct picolcd_data *data);
0206 
0207 int picolcd_resume_backlight(struct picolcd_data *data);
0208 
0209 void picolcd_suspend_backlight(struct picolcd_data *data);
0210 #else
0211 static inline int picolcd_init_backlight(struct picolcd_data *data,
0212         struct hid_report *report)
0213 {
0214     return 0;
0215 }
0216 static inline void picolcd_exit_backlight(struct picolcd_data *data)
0217 {
0218 }
0219 static inline int picolcd_resume_backlight(struct picolcd_data *data)
0220 {
0221     return 0;
0222 }
0223 static inline void picolcd_suspend_backlight(struct picolcd_data *data)
0224 {
0225 }
0226 
0227 #endif /* CONFIG_HID_PICOLCD_BACKLIGHT */
0228 
0229 
0230 #ifdef CONFIG_HID_PICOLCD_LCD
0231 int picolcd_init_lcd(struct picolcd_data *data,
0232         struct hid_report *report);
0233 
0234 void picolcd_exit_lcd(struct picolcd_data *data);
0235 
0236 int picolcd_resume_lcd(struct picolcd_data *data);
0237 #else
0238 static inline int picolcd_init_lcd(struct picolcd_data *data,
0239         struct hid_report *report)
0240 {
0241     return 0;
0242 }
0243 static inline void picolcd_exit_lcd(struct picolcd_data *data)
0244 {
0245 }
0246 static inline int picolcd_resume_lcd(struct picolcd_data *data)
0247 {
0248     return 0;
0249 }
0250 #endif /* CONFIG_HID_PICOLCD_LCD */
0251 
0252 
0253 #ifdef CONFIG_HID_PICOLCD_LEDS
0254 int picolcd_init_leds(struct picolcd_data *data,
0255         struct hid_report *report);
0256 
0257 void picolcd_exit_leds(struct picolcd_data *data);
0258 
0259 void picolcd_leds_set(struct picolcd_data *data);
0260 #else
0261 static inline int picolcd_init_leds(struct picolcd_data *data,
0262         struct hid_report *report)
0263 {
0264     return 0;
0265 }
0266 static inline void picolcd_exit_leds(struct picolcd_data *data)
0267 {
0268 }
0269 static inline void picolcd_leds_set(struct picolcd_data *data)
0270 {
0271 }
0272 #endif /* CONFIG_HID_PICOLCD_LEDS */
0273 
0274 
0275 #ifdef CONFIG_HID_PICOLCD_CIR
0276 int picolcd_raw_cir(struct picolcd_data *data,
0277         struct hid_report *report, u8 *raw_data, int size);
0278 
0279 int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report);
0280 
0281 void picolcd_exit_cir(struct picolcd_data *data);
0282 #else
0283 static inline int picolcd_raw_cir(struct picolcd_data *data,
0284         struct hid_report *report, u8 *raw_data, int size)
0285 {
0286     return 1;
0287 }
0288 static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report)
0289 {
0290     return 0;
0291 }
0292 static inline void picolcd_exit_cir(struct picolcd_data *data)
0293 {
0294 }
0295 #endif /* CONFIG_HID_PICOLCD_CIR */
0296 
0297 int picolcd_reset(struct hid_device *hdev);
0298 struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev,
0299             int report_id, const u8 *raw_data, int size);