]> Git Repo - linux.git/blob - drivers/auxdisplay/ht16k33.c
crypto: akcipher - Drop sign/verify operations
[linux.git] / drivers / auxdisplay / ht16k33.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * HT16K33 driver
4  *
5  * Author: Robin van der Gracht <[email protected]>
6  *
7  * Copyright: (C) 2016 Protonic Holland.
8  * Copyright (C) 2021 Glider bv
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/interrupt.h>
14 #include <linux/i2c.h>
15 #include <linux/property.h>
16 #include <linux/fb.h>
17 #include <linux/backlight.h>
18 #include <linux/container_of.h>
19 #include <linux/input.h>
20 #include <linux/input/matrix_keypad.h>
21 #include <linux/leds.h>
22 #include <linux/workqueue.h>
23 #include <linux/mm.h>
24
25 #include <linux/map_to_7segment.h>
26 #include <linux/map_to_14segment.h>
27
28 #include <asm/unaligned.h>
29
30 #include "line-display.h"
31
32 /* Registers */
33 #define REG_SYSTEM_SETUP                0x20
34 #define REG_SYSTEM_SETUP_OSC_ON         BIT(0)
35
36 #define REG_DISPLAY_SETUP               0x80
37 #define REG_DISPLAY_SETUP_ON            BIT(0)
38 #define REG_DISPLAY_SETUP_BLINK_OFF     (0 << 1)
39 #define REG_DISPLAY_SETUP_BLINK_2HZ     (1 << 1)
40 #define REG_DISPLAY_SETUP_BLINK_1HZ     (2 << 1)
41 #define REG_DISPLAY_SETUP_BLINK_0HZ5    (3 << 1)
42
43 #define REG_ROWINT_SET                  0xA0
44 #define REG_ROWINT_SET_INT_EN           BIT(0)
45 #define REG_ROWINT_SET_INT_ACT_HIGH     BIT(1)
46
47 #define REG_BRIGHTNESS                  0xE0
48
49 /* Defines */
50 #define DRIVER_NAME                     "ht16k33"
51
52 #define MIN_BRIGHTNESS                  0x1
53 #define MAX_BRIGHTNESS                  0x10
54
55 #define HT16K33_MATRIX_LED_MAX_COLS     8
56 #define HT16K33_MATRIX_LED_MAX_ROWS     16
57 #define HT16K33_MATRIX_KEYPAD_MAX_COLS  3
58 #define HT16K33_MATRIX_KEYPAD_MAX_ROWS  12
59
60 #define BYTES_PER_ROW           (HT16K33_MATRIX_LED_MAX_ROWS / 8)
61 #define HT16K33_FB_SIZE         (HT16K33_MATRIX_LED_MAX_COLS * BYTES_PER_ROW)
62
63 enum display_type {
64         DISP_MATRIX = 0,
65         DISP_QUAD_7SEG,
66         DISP_QUAD_14SEG,
67 };
68
69 struct ht16k33_keypad {
70         struct i2c_client *client;
71         struct input_dev *dev;
72         uint32_t cols;
73         uint32_t rows;
74         uint32_t row_shift;
75         uint32_t debounce_ms;
76         uint16_t last_key_state[HT16K33_MATRIX_KEYPAD_MAX_COLS];
77
78         wait_queue_head_t wait;
79         bool stopped;
80 };
81
82 struct ht16k33_fbdev {
83         struct fb_info *info;
84         uint32_t refresh_rate;
85         uint8_t *buffer;
86         uint8_t *cache;
87 };
88
89 struct ht16k33_priv {
90         struct i2c_client *client;
91         struct delayed_work work;
92         struct led_classdev led;
93         struct ht16k33_keypad keypad;
94         union {
95                 struct ht16k33_fbdev fbdev;
96                 struct linedisp linedisp;
97         };
98         enum display_type type;
99         uint8_t blink;
100 };
101
102 #define ht16k33_work_to_priv(p)                         \
103         container_of(p, struct ht16k33_priv, work.work)
104
105 #define ht16k33_led_to_priv(p)                          \
106         container_of(p, struct ht16k33_priv, led)
107
108 #define ht16k33_linedisp_to_priv(p)                     \
109         container_of(p, struct ht16k33_priv, linedisp)
110
111 static const struct fb_fix_screeninfo ht16k33_fb_fix = {
112         .id             = DRIVER_NAME,
113         .type           = FB_TYPE_PACKED_PIXELS,
114         .visual         = FB_VISUAL_MONO10,
115         .xpanstep       = 0,
116         .ypanstep       = 0,
117         .ywrapstep      = 0,
118         .line_length    = HT16K33_MATRIX_LED_MAX_ROWS,
119         .accel          = FB_ACCEL_NONE,
120 };
121
122 static const struct fb_var_screeninfo ht16k33_fb_var = {
123         .xres = HT16K33_MATRIX_LED_MAX_ROWS,
124         .yres = HT16K33_MATRIX_LED_MAX_COLS,
125         .xres_virtual = HT16K33_MATRIX_LED_MAX_ROWS,
126         .yres_virtual = HT16K33_MATRIX_LED_MAX_COLS,
127         .bits_per_pixel = 1,
128         .red = { 0, 1, 0 },
129         .green = { 0, 1, 0 },
130         .blue = { 0, 1, 0 },
131         .left_margin = 0,
132         .right_margin = 0,
133         .upper_margin = 0,
134         .lower_margin = 0,
135         .vmode = FB_VMODE_NONINTERLACED,
136 };
137
138 static int ht16k33_display_on(struct ht16k33_priv *priv)
139 {
140         uint8_t data = REG_DISPLAY_SETUP | REG_DISPLAY_SETUP_ON | priv->blink;
141
142         return i2c_smbus_write_byte(priv->client, data);
143 }
144
145 static int ht16k33_display_off(struct ht16k33_priv *priv)
146 {
147         return i2c_smbus_write_byte(priv->client, REG_DISPLAY_SETUP);
148 }
149
150 static int ht16k33_brightness_set(struct ht16k33_priv *priv,
151                                   unsigned int brightness)
152 {
153         int err;
154
155         if (brightness == 0) {
156                 priv->blink = REG_DISPLAY_SETUP_BLINK_OFF;
157                 return ht16k33_display_off(priv);
158         }
159
160         err = ht16k33_display_on(priv);
161         if (err)
162                 return err;
163
164         return i2c_smbus_write_byte(priv->client,
165                                     REG_BRIGHTNESS | (brightness - 1));
166 }
167
168 static int ht16k33_brightness_set_blocking(struct led_classdev *led_cdev,
169                                            enum led_brightness brightness)
170 {
171         struct ht16k33_priv *priv = ht16k33_led_to_priv(led_cdev);
172
173         return ht16k33_brightness_set(priv, brightness);
174 }
175
176 static int ht16k33_blink_set(struct led_classdev *led_cdev,
177                              unsigned long *delay_on, unsigned long *delay_off)
178 {
179         struct ht16k33_priv *priv = ht16k33_led_to_priv(led_cdev);
180         unsigned int delay;
181         uint8_t blink;
182         int err;
183
184         if (!*delay_on && !*delay_off) {
185                 blink = REG_DISPLAY_SETUP_BLINK_1HZ;
186                 delay = 1000;
187         } else if (*delay_on <= 750) {
188                 blink = REG_DISPLAY_SETUP_BLINK_2HZ;
189                 delay = 500;
190         } else if (*delay_on <= 1500) {
191                 blink = REG_DISPLAY_SETUP_BLINK_1HZ;
192                 delay = 1000;
193         } else {
194                 blink = REG_DISPLAY_SETUP_BLINK_0HZ5;
195                 delay = 2000;
196         }
197
198         err = i2c_smbus_write_byte(priv->client,
199                                    REG_DISPLAY_SETUP | REG_DISPLAY_SETUP_ON |
200                                    blink);
201         if (err)
202                 return err;
203
204         priv->blink = blink;
205         *delay_on = *delay_off = delay;
206         return 0;
207 }
208
209 static void ht16k33_fb_queue(struct ht16k33_priv *priv)
210 {
211         struct ht16k33_fbdev *fbdev = &priv->fbdev;
212
213         schedule_delayed_work(&priv->work, HZ / fbdev->refresh_rate);
214 }
215
216 /*
217  * This gets the fb data from cache and copies it to ht16k33 display RAM
218  */
219 static void ht16k33_fb_update(struct work_struct *work)
220 {
221         struct ht16k33_priv *priv = ht16k33_work_to_priv(work);
222         struct ht16k33_fbdev *fbdev = &priv->fbdev;
223
224         uint8_t *p1, *p2;
225         int len, pos = 0, first = -1;
226
227         p1 = fbdev->cache;
228         p2 = fbdev->buffer;
229
230         /* Search for the first byte with changes */
231         while (pos < HT16K33_FB_SIZE && first < 0) {
232                 if (*(p1++) - *(p2++))
233                         first = pos;
234                 pos++;
235         }
236
237         /* No changes found */
238         if (first < 0)
239                 goto requeue;
240
241         len = HT16K33_FB_SIZE - first;
242         p1 = fbdev->cache + HT16K33_FB_SIZE - 1;
243         p2 = fbdev->buffer + HT16K33_FB_SIZE - 1;
244
245         /* Determine i2c transfer length */
246         while (len > 1) {
247                 if (*(p1--) - *(p2--))
248                         break;
249                 len--;
250         }
251
252         p1 = fbdev->cache + first;
253         p2 = fbdev->buffer + first;
254         if (!i2c_smbus_write_i2c_block_data(priv->client, first, len, p2))
255                 memcpy(p1, p2, len);
256 requeue:
257         ht16k33_fb_queue(priv);
258 }
259
260 static int ht16k33_initialize(struct ht16k33_priv *priv)
261 {
262         uint8_t data[HT16K33_FB_SIZE];
263         uint8_t byte;
264         int err;
265
266         /* Clear RAM (8 * 16 bits) */
267         memset(data, 0, sizeof(data));
268         err = i2c_smbus_write_block_data(priv->client, 0, sizeof(data), data);
269         if (err)
270                 return err;
271
272         /* Turn on internal oscillator */
273         byte = REG_SYSTEM_SETUP_OSC_ON | REG_SYSTEM_SETUP;
274         err = i2c_smbus_write_byte(priv->client, byte);
275         if (err)
276                 return err;
277
278         /* Configure INT pin */
279         byte = REG_ROWINT_SET | REG_ROWINT_SET_INT_ACT_HIGH;
280         if (priv->client->irq > 0)
281                 byte |= REG_ROWINT_SET_INT_EN;
282         return i2c_smbus_write_byte(priv->client, byte);
283 }
284
285 static int ht16k33_bl_update_status(struct backlight_device *bl)
286 {
287         const int brightness = backlight_get_brightness(bl);
288         struct ht16k33_priv *priv = bl_get_data(bl);
289
290         return ht16k33_brightness_set(priv, brightness);
291 }
292
293 static const struct backlight_ops ht16k33_bl_ops = {
294         .update_status  = ht16k33_bl_update_status,
295 };
296
297 /*
298  * Blank events will be passed to the actual device handling the backlight when
299  * we return zero here.
300  */
301 static int ht16k33_blank(int blank, struct fb_info *info)
302 {
303         return 0;
304 }
305
306 static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma)
307 {
308         struct ht16k33_priv *priv = info->par;
309         struct page *pages = virt_to_page(priv->fbdev.buffer);
310
311         vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
312
313         return vm_map_pages_zero(vma, &pages, 1);
314 }
315
316 static const struct fb_ops ht16k33_fb_ops = {
317         .owner = THIS_MODULE,
318         __FB_DEFAULT_SYSMEM_OPS_RDWR,
319         .fb_blank = ht16k33_blank,
320         __FB_DEFAULT_SYSMEM_OPS_DRAW,
321         .fb_mmap = ht16k33_mmap,
322 };
323
324 /*
325  * This gets the keys from keypad and reports it to input subsystem.
326  * Returns true if a key is pressed.
327  */
328 static bool ht16k33_keypad_scan(struct ht16k33_keypad *keypad)
329 {
330         const unsigned short *keycodes = keypad->dev->keycode;
331         u16 new_state[HT16K33_MATRIX_KEYPAD_MAX_COLS];
332         __le16 data[HT16K33_MATRIX_KEYPAD_MAX_COLS];
333         unsigned long bits_changed;
334         int row, col, code;
335         int rc;
336         bool pressed = false;
337
338         rc = i2c_smbus_read_i2c_block_data(keypad->client, 0x40,
339                                            sizeof(data), (u8 *)data);
340         if (rc != sizeof(data)) {
341                 dev_err(&keypad->client->dev,
342                         "Failed to read key data, rc=%d\n", rc);
343                 return false;
344         }
345
346         for (col = 0; col < keypad->cols; col++) {
347                 new_state[col] = le16_to_cpu(data[col]);
348                 if (new_state[col])
349                         pressed = true;
350                 bits_changed = keypad->last_key_state[col] ^ new_state[col];
351
352                 for_each_set_bit(row, &bits_changed, BITS_PER_LONG) {
353                         code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
354                         input_event(keypad->dev, EV_MSC, MSC_SCAN, code);
355                         input_report_key(keypad->dev, keycodes[code],
356                                          new_state[col] & BIT(row));
357                 }
358         }
359         input_sync(keypad->dev);
360         memcpy(keypad->last_key_state, new_state, sizeof(u16) * keypad->cols);
361
362         return pressed;
363 }
364
365 static irqreturn_t ht16k33_keypad_irq_thread(int irq, void *dev)
366 {
367         struct ht16k33_keypad *keypad = dev;
368
369         do {
370                 wait_event_timeout(keypad->wait, keypad->stopped,
371                                     msecs_to_jiffies(keypad->debounce_ms));
372                 if (keypad->stopped)
373                         break;
374         } while (ht16k33_keypad_scan(keypad));
375
376         return IRQ_HANDLED;
377 }
378
379 static int ht16k33_keypad_start(struct input_dev *dev)
380 {
381         struct ht16k33_keypad *keypad = input_get_drvdata(dev);
382
383         keypad->stopped = false;
384         mb();
385         enable_irq(keypad->client->irq);
386
387         return 0;
388 }
389
390 static void ht16k33_keypad_stop(struct input_dev *dev)
391 {
392         struct ht16k33_keypad *keypad = input_get_drvdata(dev);
393
394         keypad->stopped = true;
395         mb();
396         wake_up(&keypad->wait);
397         disable_irq(keypad->client->irq);
398 }
399
400 static void ht16k33_seg7_update(struct work_struct *work)
401 {
402         struct ht16k33_priv *priv = ht16k33_work_to_priv(work);
403         struct linedisp_map *map = priv->linedisp.map;
404         char *s = priv->linedisp.buf;
405         uint8_t buf[9];
406
407         buf[0] = map_to_seg7(&map->map.seg7, *s++);
408         buf[1] = 0;
409         buf[2] = map_to_seg7(&map->map.seg7, *s++);
410         buf[3] = 0;
411         buf[4] = 0;
412         buf[5] = 0;
413         buf[6] = map_to_seg7(&map->map.seg7, *s++);
414         buf[7] = 0;
415         buf[8] = map_to_seg7(&map->map.seg7, *s++);
416
417         i2c_smbus_write_i2c_block_data(priv->client, 0, ARRAY_SIZE(buf), buf);
418 }
419
420 static void ht16k33_seg14_update(struct work_struct *work)
421 {
422         struct ht16k33_priv *priv = ht16k33_work_to_priv(work);
423         struct linedisp_map *map = priv->linedisp.map;
424         char *s = priv->linedisp.buf;
425         uint8_t buf[8];
426
427         put_unaligned_le16(map_to_seg14(&map->map.seg14, *s++), buf + 0);
428         put_unaligned_le16(map_to_seg14(&map->map.seg14, *s++), buf + 2);
429         put_unaligned_le16(map_to_seg14(&map->map.seg14, *s++), buf + 4);
430         put_unaligned_le16(map_to_seg14(&map->map.seg14, *s++), buf + 6);
431
432         i2c_smbus_write_i2c_block_data(priv->client, 0, ARRAY_SIZE(buf), buf);
433 }
434
435 static int ht16k33_linedisp_get_map_type(struct linedisp *linedisp)
436 {
437         struct ht16k33_priv *priv = ht16k33_linedisp_to_priv(linedisp);
438
439         switch (priv->type) {
440         case DISP_QUAD_7SEG:
441                 INIT_DELAYED_WORK(&priv->work, ht16k33_seg7_update);
442                 return LINEDISP_MAP_SEG7;
443
444         case DISP_QUAD_14SEG:
445                 INIT_DELAYED_WORK(&priv->work, ht16k33_seg14_update);
446                 return LINEDISP_MAP_SEG14;
447
448         default:
449                 return -EINVAL;
450         }
451 }
452
453 static void ht16k33_linedisp_update(struct linedisp *linedisp)
454 {
455         struct ht16k33_priv *priv = ht16k33_linedisp_to_priv(linedisp);
456
457         schedule_delayed_work(&priv->work, 0);
458 }
459
460 static const struct linedisp_ops ht16k33_linedisp_ops = {
461         .get_map_type = ht16k33_linedisp_get_map_type,
462         .update = ht16k33_linedisp_update,
463 };
464
465 static int ht16k33_led_probe(struct device *dev, struct led_classdev *led,
466                              unsigned int brightness)
467 {
468         struct led_init_data init_data = {};
469         int err;
470
471         /* The LED is optional */
472         init_data.fwnode = device_get_named_child_node(dev, "led");
473         if (!init_data.fwnode)
474                 return 0;
475
476         init_data.devicename = "auxdisplay";
477         init_data.devname_mandatory = true;
478
479         led->brightness_set_blocking = ht16k33_brightness_set_blocking;
480         led->blink_set = ht16k33_blink_set;
481         led->flags = LED_CORE_SUSPENDRESUME;
482         led->brightness = brightness;
483         led->max_brightness = MAX_BRIGHTNESS;
484
485         err = devm_led_classdev_register_ext(dev, led, &init_data);
486         fwnode_handle_put(init_data.fwnode);
487         if (err)
488                 dev_err(dev, "Failed to register LED\n");
489
490         return err;
491 }
492
493 static int ht16k33_keypad_probe(struct i2c_client *client,
494                                 struct ht16k33_keypad *keypad)
495 {
496         struct device *dev = &client->dev;
497         u32 rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS;
498         u32 cols = HT16K33_MATRIX_KEYPAD_MAX_COLS;
499         int err;
500
501         keypad->client = client;
502         init_waitqueue_head(&keypad->wait);
503
504         keypad->dev = devm_input_allocate_device(dev);
505         if (!keypad->dev)
506                 return -ENOMEM;
507
508         input_set_drvdata(keypad->dev, keypad);
509
510         keypad->dev->name = DRIVER_NAME"-keypad";
511         keypad->dev->id.bustype = BUS_I2C;
512         keypad->dev->open = ht16k33_keypad_start;
513         keypad->dev->close = ht16k33_keypad_stop;
514
515         if (!device_property_read_bool(dev, "linux,no-autorepeat"))
516                 __set_bit(EV_REP, keypad->dev->evbit);
517
518         err = device_property_read_u32(dev, "debounce-delay-ms",
519                                        &keypad->debounce_ms);
520         if (err) {
521                 dev_err(dev, "key debounce delay not specified\n");
522                 return err;
523         }
524
525         err = matrix_keypad_parse_properties(dev, &rows, &cols);
526         if (err)
527                 return err;
528         if (rows > HT16K33_MATRIX_KEYPAD_MAX_ROWS ||
529             cols > HT16K33_MATRIX_KEYPAD_MAX_COLS) {
530                 dev_err(dev, "%u rows or %u cols out of range in DT\n", rows,
531                         cols);
532                 return -ERANGE;
533         }
534
535         keypad->rows = rows;
536         keypad->cols = cols;
537         keypad->row_shift = get_count_order(cols);
538
539         err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
540                                          keypad->dev);
541         if (err) {
542                 dev_err(dev, "failed to build keymap\n");
543                 return err;
544         }
545
546         err = devm_request_threaded_irq(dev, client->irq, NULL,
547                                         ht16k33_keypad_irq_thread,
548                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
549                                         DRIVER_NAME, keypad);
550         if (err) {
551                 dev_err(dev, "irq request failed %d, error %d\n", client->irq,
552                         err);
553                 return err;
554         }
555
556         ht16k33_keypad_stop(keypad->dev);
557
558         return input_register_device(keypad->dev);
559 }
560
561 static int ht16k33_fbdev_probe(struct device *dev, struct ht16k33_priv *priv,
562                                uint32_t brightness)
563 {
564         struct ht16k33_fbdev *fbdev = &priv->fbdev;
565         struct backlight_device *bl = NULL;
566         int err;
567
568         if (priv->led.dev) {
569                 err = ht16k33_brightness_set(priv, brightness);
570                 if (err)
571                         return err;
572         } else {
573                 /* backwards compatibility with DT lacking an led subnode */
574                 struct backlight_properties bl_props;
575
576                 memset(&bl_props, 0, sizeof(struct backlight_properties));
577                 bl_props.type = BACKLIGHT_RAW;
578                 bl_props.max_brightness = MAX_BRIGHTNESS;
579
580                 bl = devm_backlight_device_register(dev, DRIVER_NAME"-bl", dev,
581                                                     priv, &ht16k33_bl_ops,
582                                                     &bl_props);
583                 if (IS_ERR(bl)) {
584                         dev_err(dev, "failed to register backlight\n");
585                         return PTR_ERR(bl);
586                 }
587
588                 bl->props.brightness = brightness;
589                 ht16k33_bl_update_status(bl);
590         }
591
592         /* Framebuffer (2 bytes per column) */
593         BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE);
594         fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL);
595         if (!fbdev->buffer)
596                 return -ENOMEM;
597
598         fbdev->cache = devm_kmalloc(dev, HT16K33_FB_SIZE, GFP_KERNEL);
599         if (!fbdev->cache) {
600                 err = -ENOMEM;
601                 goto err_fbdev_buffer;
602         }
603
604         fbdev->info = framebuffer_alloc(0, dev);
605         if (!fbdev->info) {
606                 err = -ENOMEM;
607                 goto err_fbdev_buffer;
608         }
609
610         err = device_property_read_u32(dev, "refresh-rate-hz",
611                                        &fbdev->refresh_rate);
612         if (err) {
613                 dev_err(dev, "refresh rate not specified\n");
614                 goto err_fbdev_info;
615         }
616         fb_bl_default_curve(fbdev->info, 0, MIN_BRIGHTNESS, MAX_BRIGHTNESS);
617
618         INIT_DELAYED_WORK(&priv->work, ht16k33_fb_update);
619         fbdev->info->fbops = &ht16k33_fb_ops;
620         fbdev->info->flags |= FBINFO_VIRTFB;
621         fbdev->info->screen_buffer = fbdev->buffer;
622         fbdev->info->screen_size = HT16K33_FB_SIZE;
623         fbdev->info->fix = ht16k33_fb_fix;
624         fbdev->info->var = ht16k33_fb_var;
625         fbdev->info->bl_dev = bl;
626         fbdev->info->pseudo_palette = NULL;
627         fbdev->info->par = priv;
628
629         err = register_framebuffer(fbdev->info);
630         if (err)
631                 goto err_fbdev_info;
632
633         ht16k33_fb_queue(priv);
634         return 0;
635
636 err_fbdev_info:
637         framebuffer_release(fbdev->info);
638 err_fbdev_buffer:
639         free_page((unsigned long) fbdev->buffer);
640
641         return err;
642 }
643
644 static int ht16k33_seg_probe(struct device *dev, struct ht16k33_priv *priv,
645                              uint32_t brightness)
646 {
647         struct linedisp *linedisp = &priv->linedisp;
648         int err;
649
650         err = ht16k33_brightness_set(priv, brightness);
651         if (err)
652                 return err;
653
654         return linedisp_register(linedisp, dev, 4, &ht16k33_linedisp_ops);
655 }
656
657 static int ht16k33_probe(struct i2c_client *client)
658 {
659         struct device *dev = &client->dev;
660         const struct of_device_id *id;
661         struct ht16k33_priv *priv;
662         uint32_t dft_brightness;
663         int err;
664
665         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
666                 dev_err(dev, "i2c_check_functionality error\n");
667                 return -EIO;
668         }
669
670         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
671         if (!priv)
672                 return -ENOMEM;
673
674         priv->client = client;
675         id = i2c_of_match_device(dev->driver->of_match_table, client);
676         if (id)
677                 priv->type = (uintptr_t)id->data;
678         i2c_set_clientdata(client, priv);
679
680         err = ht16k33_initialize(priv);
681         if (err)
682                 return err;
683
684         err = device_property_read_u32(dev, "default-brightness-level",
685                                        &dft_brightness);
686         if (err) {
687                 dft_brightness = MAX_BRIGHTNESS;
688         } else if (dft_brightness > MAX_BRIGHTNESS) {
689                 dev_warn(dev,
690                          "invalid default brightness level: %u, using %u\n",
691                          dft_brightness, MAX_BRIGHTNESS);
692                 dft_brightness = MAX_BRIGHTNESS;
693         }
694
695         /* LED */
696         err = ht16k33_led_probe(dev, &priv->led, dft_brightness);
697         if (err)
698                 return err;
699
700         /* Keypad */
701         if (client->irq > 0) {
702                 err = ht16k33_keypad_probe(client, &priv->keypad);
703                 if (err)
704                         return err;
705         }
706
707         switch (priv->type) {
708         case DISP_MATRIX:
709                 /* Frame Buffer Display */
710                 err = ht16k33_fbdev_probe(dev, priv, dft_brightness);
711                 break;
712
713         case DISP_QUAD_7SEG:
714         case DISP_QUAD_14SEG:
715                 /* Segment Display */
716                 err = ht16k33_seg_probe(dev, priv, dft_brightness);
717                 break;
718
719         default:
720                 return -EINVAL;
721         }
722         return err;
723 }
724
725 static void ht16k33_remove(struct i2c_client *client)
726 {
727         struct ht16k33_priv *priv = i2c_get_clientdata(client);
728         struct ht16k33_fbdev *fbdev = &priv->fbdev;
729
730         cancel_delayed_work_sync(&priv->work);
731
732         switch (priv->type) {
733         case DISP_MATRIX:
734                 unregister_framebuffer(fbdev->info);
735                 framebuffer_release(fbdev->info);
736                 free_page((unsigned long)fbdev->buffer);
737                 break;
738
739         case DISP_QUAD_7SEG:
740         case DISP_QUAD_14SEG:
741                 linedisp_unregister(&priv->linedisp);
742                 break;
743
744         default:
745                 break;
746         }
747 }
748
749 static const struct i2c_device_id ht16k33_i2c_match[] = {
750         { "ht16k33", 0 },
751         { }
752 };
753 MODULE_DEVICE_TABLE(i2c, ht16k33_i2c_match);
754
755 static const struct of_device_id ht16k33_of_match[] = {
756         {
757                 /* 0.56" 4-Digit 7-Segment FeatherWing Display (Red) */
758                 .compatible = "adafruit,3108", .data = (void *)DISP_QUAD_7SEG,
759         }, {
760                 /* 0.54" Quad Alphanumeric FeatherWing Display (Red) */
761                 .compatible = "adafruit,3130", .data = (void *)DISP_QUAD_14SEG,
762         }, {
763                 /* Generic, assumed Dot-Matrix Display */
764                 .compatible = "holtek,ht16k33", .data = (void *)DISP_MATRIX,
765         },
766         { }
767 };
768 MODULE_DEVICE_TABLE(of, ht16k33_of_match);
769
770 static struct i2c_driver ht16k33_driver = {
771         .probe          = ht16k33_probe,
772         .remove         = ht16k33_remove,
773         .driver         = {
774                 .name           = DRIVER_NAME,
775                 .of_match_table = ht16k33_of_match,
776         },
777         .id_table = ht16k33_i2c_match,
778 };
779 module_i2c_driver(ht16k33_driver);
780
781 MODULE_DESCRIPTION("Holtek HT16K33 driver");
782 MODULE_LICENSE("GPL");
783 MODULE_IMPORT_NS(LINEDISP);
784 MODULE_AUTHOR("Robin van der Gracht <[email protected]>");
This page took 0.07822 seconds and 4 git commands to generate.