1 // SPDX-License-Identifier: GPL-2.0
5 * Author: Robin van der Gracht <robin@protonic.nl>
7 * Copyright: (C) 2016 Protonic Holland.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/interrupt.h>
13 #include <linux/i2c.h>
16 #include <linux/slab.h>
17 #include <linux/backlight.h>
18 #include <linux/input.h>
19 #include <linux/input/matrix_keypad.h>
20 #include <linux/workqueue.h>
24 #define REG_SYSTEM_SETUP 0x20
25 #define REG_SYSTEM_SETUP_OSC_ON BIT(0)
27 #define REG_DISPLAY_SETUP 0x80
28 #define REG_DISPLAY_SETUP_ON BIT(0)
30 #define REG_ROWINT_SET 0xA0
31 #define REG_ROWINT_SET_INT_EN BIT(0)
32 #define REG_ROWINT_SET_INT_ACT_HIGH BIT(1)
34 #define REG_BRIGHTNESS 0xE0
37 #define DRIVER_NAME "ht16k33"
39 #define MIN_BRIGHTNESS 0x1
40 #define MAX_BRIGHTNESS 0x10
42 #define HT16K33_MATRIX_LED_MAX_COLS 8
43 #define HT16K33_MATRIX_LED_MAX_ROWS 16
44 #define HT16K33_MATRIX_KEYPAD_MAX_COLS 3
45 #define HT16K33_MATRIX_KEYPAD_MAX_ROWS 12
47 #define BYTES_PER_ROW (HT16K33_MATRIX_LED_MAX_ROWS / 8)
48 #define HT16K33_FB_SIZE (HT16K33_MATRIX_LED_MAX_COLS * BYTES_PER_ROW)
50 struct ht16k33_keypad
{
51 struct i2c_client
*client
;
52 struct input_dev
*dev
;
57 uint16_t last_key_state
[HT16K33_MATRIX_KEYPAD_MAX_COLS
];
59 wait_queue_head_t wait
;
63 struct ht16k33_fbdev
{
65 uint32_t refresh_rate
;
68 struct delayed_work work
;
72 struct i2c_client
*client
;
73 struct ht16k33_keypad keypad
;
74 struct ht16k33_fbdev fbdev
;
77 static struct fb_fix_screeninfo ht16k33_fb_fix
= {
79 .type
= FB_TYPE_PACKED_PIXELS
,
80 .visual
= FB_VISUAL_MONO10
,
84 .line_length
= HT16K33_MATRIX_LED_MAX_ROWS
,
85 .accel
= FB_ACCEL_NONE
,
88 static struct fb_var_screeninfo ht16k33_fb_var
= {
89 .xres
= HT16K33_MATRIX_LED_MAX_ROWS
,
90 .yres
= HT16K33_MATRIX_LED_MAX_COLS
,
91 .xres_virtual
= HT16K33_MATRIX_LED_MAX_ROWS
,
92 .yres_virtual
= HT16K33_MATRIX_LED_MAX_COLS
,
101 .vmode
= FB_VMODE_NONINTERLACED
,
104 static int ht16k33_display_on(struct ht16k33_priv
*priv
)
106 uint8_t data
= REG_DISPLAY_SETUP
| REG_DISPLAY_SETUP_ON
;
108 return i2c_smbus_write_byte(priv
->client
, data
);
111 static int ht16k33_display_off(struct ht16k33_priv
*priv
)
113 return i2c_smbus_write_byte(priv
->client
, REG_DISPLAY_SETUP
);
116 static void ht16k33_fb_queue(struct ht16k33_priv
*priv
)
118 struct ht16k33_fbdev
*fbdev
= &priv
->fbdev
;
120 schedule_delayed_work(&fbdev
->work
,
121 msecs_to_jiffies(HZ
/ fbdev
->refresh_rate
));
125 * This gets the fb data from cache and copies it to ht16k33 display RAM
127 static void ht16k33_fb_update(struct work_struct
*work
)
129 struct ht16k33_fbdev
*fbdev
=
130 container_of(work
, struct ht16k33_fbdev
, work
.work
);
131 struct ht16k33_priv
*priv
=
132 container_of(fbdev
, struct ht16k33_priv
, fbdev
);
135 int len
, pos
= 0, first
= -1;
140 /* Search for the first byte with changes */
141 while (pos
< HT16K33_FB_SIZE
&& first
< 0) {
142 if (*(p1
++) - *(p2
++))
147 /* No changes found */
151 len
= HT16K33_FB_SIZE
- first
;
152 p1
= fbdev
->cache
+ HT16K33_FB_SIZE
- 1;
153 p2
= fbdev
->buffer
+ HT16K33_FB_SIZE
- 1;
155 /* Determine i2c transfer length */
157 if (*(p1
--) - *(p2
--))
162 p1
= fbdev
->cache
+ first
;
163 p2
= fbdev
->buffer
+ first
;
164 if (!i2c_smbus_write_i2c_block_data(priv
->client
, first
, len
, p2
))
167 ht16k33_fb_queue(priv
);
170 static int ht16k33_initialize(struct ht16k33_priv
*priv
)
174 uint8_t data
[HT16K33_MATRIX_LED_MAX_COLS
* 2];
176 /* Clear RAM (8 * 16 bits) */
177 memset(data
, 0, sizeof(data
));
178 err
= i2c_smbus_write_block_data(priv
->client
, 0, sizeof(data
), data
);
182 /* Turn on internal oscillator */
183 byte
= REG_SYSTEM_SETUP_OSC_ON
| REG_SYSTEM_SETUP
;
184 err
= i2c_smbus_write_byte(priv
->client
, byte
);
188 /* Configure INT pin */
189 byte
= REG_ROWINT_SET
| REG_ROWINT_SET_INT_ACT_HIGH
;
190 if (priv
->client
->irq
> 0)
191 byte
|= REG_ROWINT_SET_INT_EN
;
192 return i2c_smbus_write_byte(priv
->client
, byte
);
195 static int ht16k33_bl_update_status(struct backlight_device
*bl
)
197 int brightness
= bl
->props
.brightness
;
198 struct ht16k33_priv
*priv
= bl_get_data(bl
);
200 if (bl
->props
.power
!= FB_BLANK_UNBLANK
||
201 bl
->props
.fb_blank
!= FB_BLANK_UNBLANK
||
202 bl
->props
.state
& BL_CORE_FBBLANK
|| brightness
== 0) {
203 return ht16k33_display_off(priv
);
206 ht16k33_display_on(priv
);
207 return i2c_smbus_write_byte(priv
->client
,
208 REG_BRIGHTNESS
| (brightness
- 1));
211 static int ht16k33_bl_check_fb(struct backlight_device
*bl
, struct fb_info
*fi
)
213 struct ht16k33_priv
*priv
= bl_get_data(bl
);
215 return (fi
== NULL
) || (fi
->par
== priv
);
218 static const struct backlight_ops ht16k33_bl_ops
= {
219 .update_status
= ht16k33_bl_update_status
,
220 .check_fb
= ht16k33_bl_check_fb
,
223 static int ht16k33_mmap(struct fb_info
*info
, struct vm_area_struct
*vma
)
225 struct ht16k33_priv
*priv
= info
->par
;
227 return vm_insert_page(vma
, vma
->vm_start
,
228 virt_to_page(priv
->fbdev
.buffer
));
231 static struct fb_ops ht16k33_fb_ops
= {
232 .owner
= THIS_MODULE
,
233 .fb_read
= fb_sys_read
,
234 .fb_write
= fb_sys_write
,
235 .fb_fillrect
= sys_fillrect
,
236 .fb_copyarea
= sys_copyarea
,
237 .fb_imageblit
= sys_imageblit
,
238 .fb_mmap
= ht16k33_mmap
,
242 * This gets the keys from keypad and reports it to input subsystem.
243 * Returns true if a key is pressed.
245 static bool ht16k33_keypad_scan(struct ht16k33_keypad
*keypad
)
247 const unsigned short *keycodes
= keypad
->dev
->keycode
;
248 u16 new_state
[HT16K33_MATRIX_KEYPAD_MAX_COLS
];
249 __le16 data
[HT16K33_MATRIX_KEYPAD_MAX_COLS
];
250 unsigned long bits_changed
;
253 bool pressed
= false;
255 rc
= i2c_smbus_read_i2c_block_data(keypad
->client
, 0x40,
256 sizeof(data
), (u8
*)data
);
257 if (rc
!= sizeof(data
)) {
258 dev_err(&keypad
->client
->dev
,
259 "Failed to read key data, rc=%d\n", rc
);
263 for (col
= 0; col
< keypad
->cols
; col
++) {
264 new_state
[col
] = le16_to_cpu(data
[col
]);
267 bits_changed
= keypad
->last_key_state
[col
] ^ new_state
[col
];
269 for_each_set_bit(row
, &bits_changed
, BITS_PER_LONG
) {
270 code
= MATRIX_SCAN_CODE(row
, col
, keypad
->row_shift
);
271 input_event(keypad
->dev
, EV_MSC
, MSC_SCAN
, code
);
272 input_report_key(keypad
->dev
, keycodes
[code
],
273 new_state
[col
] & BIT(row
));
276 input_sync(keypad
->dev
);
277 memcpy(keypad
->last_key_state
, new_state
, sizeof(u16
) * keypad
->cols
);
282 static irqreturn_t
ht16k33_keypad_irq_thread(int irq
, void *dev
)
284 struct ht16k33_keypad
*keypad
= dev
;
287 wait_event_timeout(keypad
->wait
, keypad
->stopped
,
288 msecs_to_jiffies(keypad
->debounce_ms
));
291 } while (ht16k33_keypad_scan(keypad
));
296 static int ht16k33_keypad_start(struct input_dev
*dev
)
298 struct ht16k33_keypad
*keypad
= input_get_drvdata(dev
);
300 keypad
->stopped
= false;
302 enable_irq(keypad
->client
->irq
);
307 static void ht16k33_keypad_stop(struct input_dev
*dev
)
309 struct ht16k33_keypad
*keypad
= input_get_drvdata(dev
);
311 keypad
->stopped
= true;
313 wake_up(&keypad
->wait
);
314 disable_irq(keypad
->client
->irq
);
317 static int ht16k33_keypad_probe(struct i2c_client
*client
,
318 struct ht16k33_keypad
*keypad
)
320 struct device_node
*node
= client
->dev
.of_node
;
321 u32 rows
= HT16K33_MATRIX_KEYPAD_MAX_ROWS
;
322 u32 cols
= HT16K33_MATRIX_KEYPAD_MAX_COLS
;
325 keypad
->client
= client
;
326 init_waitqueue_head(&keypad
->wait
);
328 keypad
->dev
= devm_input_allocate_device(&client
->dev
);
332 input_set_drvdata(keypad
->dev
, keypad
);
334 keypad
->dev
->name
= DRIVER_NAME
"-keypad";
335 keypad
->dev
->id
.bustype
= BUS_I2C
;
336 keypad
->dev
->open
= ht16k33_keypad_start
;
337 keypad
->dev
->close
= ht16k33_keypad_stop
;
339 if (!of_get_property(node
, "linux,no-autorepeat", NULL
))
340 __set_bit(EV_REP
, keypad
->dev
->evbit
);
342 err
= of_property_read_u32(node
, "debounce-delay-ms",
343 &keypad
->debounce_ms
);
345 dev_err(&client
->dev
, "key debounce delay not specified\n");
349 err
= matrix_keypad_parse_of_params(&client
->dev
, &rows
, &cols
);
352 if (rows
> HT16K33_MATRIX_KEYPAD_MAX_ROWS
||
353 cols
> HT16K33_MATRIX_KEYPAD_MAX_COLS
) {
354 dev_err(&client
->dev
, "%u rows or %u cols out of range in DT\n",
361 keypad
->row_shift
= get_count_order(cols
);
363 err
= matrix_keypad_build_keymap(NULL
, NULL
, rows
, cols
, NULL
,
366 dev_err(&client
->dev
, "failed to build keymap\n");
370 err
= devm_request_threaded_irq(&client
->dev
, client
->irq
,
371 NULL
, ht16k33_keypad_irq_thread
,
372 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
373 DRIVER_NAME
, keypad
);
375 dev_err(&client
->dev
, "irq request failed %d, error %d\n",
380 ht16k33_keypad_stop(keypad
->dev
);
382 err
= input_register_device(keypad
->dev
);
389 static int ht16k33_probe(struct i2c_client
*client
,
390 const struct i2c_device_id
*id
)
393 uint32_t dft_brightness
;
394 struct backlight_device
*bl
;
395 struct backlight_properties bl_props
;
396 struct ht16k33_priv
*priv
;
397 struct ht16k33_fbdev
*fbdev
;
398 struct device_node
*node
= client
->dev
.of_node
;
400 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
)) {
401 dev_err(&client
->dev
, "i2c_check_functionality error\n");
405 if (client
->irq
<= 0) {
406 dev_err(&client
->dev
, "No IRQ specified\n");
410 priv
= devm_kzalloc(&client
->dev
, sizeof(*priv
), GFP_KERNEL
);
414 priv
->client
= client
;
415 i2c_set_clientdata(client
, priv
);
416 fbdev
= &priv
->fbdev
;
418 err
= ht16k33_initialize(priv
);
422 /* Framebuffer (2 bytes per column) */
423 BUILD_BUG_ON(PAGE_SIZE
< HT16K33_FB_SIZE
);
424 fbdev
->buffer
= (unsigned char *) get_zeroed_page(GFP_KERNEL
);
428 fbdev
->cache
= devm_kmalloc(&client
->dev
, HT16K33_FB_SIZE
, GFP_KERNEL
);
431 goto err_fbdev_buffer
;
434 fbdev
->info
= framebuffer_alloc(0, &client
->dev
);
437 goto err_fbdev_buffer
;
440 err
= of_property_read_u32(node
, "refresh-rate-hz",
441 &fbdev
->refresh_rate
);
443 dev_err(&client
->dev
, "refresh rate not specified\n");
446 fb_bl_default_curve(fbdev
->info
, 0, MIN_BRIGHTNESS
, MAX_BRIGHTNESS
);
448 INIT_DELAYED_WORK(&fbdev
->work
, ht16k33_fb_update
);
449 fbdev
->info
->fbops
= &ht16k33_fb_ops
;
450 fbdev
->info
->screen_base
= (char __iomem
*) fbdev
->buffer
;
451 fbdev
->info
->screen_size
= HT16K33_FB_SIZE
;
452 fbdev
->info
->fix
= ht16k33_fb_fix
;
453 fbdev
->info
->var
= ht16k33_fb_var
;
454 fbdev
->info
->pseudo_palette
= NULL
;
455 fbdev
->info
->flags
= FBINFO_FLAG_DEFAULT
;
456 fbdev
->info
->par
= priv
;
458 err
= register_framebuffer(fbdev
->info
);
462 err
= ht16k33_keypad_probe(client
, &priv
->keypad
);
464 goto err_fbdev_unregister
;
467 memset(&bl_props
, 0, sizeof(struct backlight_properties
));
468 bl_props
.type
= BACKLIGHT_RAW
;
469 bl_props
.max_brightness
= MAX_BRIGHTNESS
;
471 bl
= devm_backlight_device_register(&client
->dev
, DRIVER_NAME
"-bl",
473 &ht16k33_bl_ops
, &bl_props
);
475 dev_err(&client
->dev
, "failed to register backlight\n");
477 goto err_fbdev_unregister
;
480 err
= of_property_read_u32(node
, "default-brightness-level",
483 dft_brightness
= MAX_BRIGHTNESS
;
484 } else if (dft_brightness
> MAX_BRIGHTNESS
) {
485 dev_warn(&client
->dev
,
486 "invalid default brightness level: %u, using %u\n",
487 dft_brightness
, MAX_BRIGHTNESS
);
488 dft_brightness
= MAX_BRIGHTNESS
;
491 bl
->props
.brightness
= dft_brightness
;
492 ht16k33_bl_update_status(bl
);
494 ht16k33_fb_queue(priv
);
497 err_fbdev_unregister
:
498 unregister_framebuffer(fbdev
->info
);
500 framebuffer_release(fbdev
->info
);
502 free_page((unsigned long) fbdev
->buffer
);
507 static int ht16k33_remove(struct i2c_client
*client
)
509 struct ht16k33_priv
*priv
= i2c_get_clientdata(client
);
510 struct ht16k33_fbdev
*fbdev
= &priv
->fbdev
;
512 cancel_delayed_work_sync(&fbdev
->work
);
513 unregister_framebuffer(fbdev
->info
);
514 framebuffer_release(fbdev
->info
);
515 free_page((unsigned long) fbdev
->buffer
);
520 static const struct i2c_device_id ht16k33_i2c_match
[] = {
524 MODULE_DEVICE_TABLE(i2c
, ht16k33_i2c_match
);
526 static const struct of_device_id ht16k33_of_match
[] = {
527 { .compatible
= "holtek,ht16k33", },
530 MODULE_DEVICE_TABLE(of
, ht16k33_of_match
);
532 static struct i2c_driver ht16k33_driver
= {
533 .probe
= ht16k33_probe
,
534 .remove
= ht16k33_remove
,
537 .of_match_table
= of_match_ptr(ht16k33_of_match
),
539 .id_table
= ht16k33_i2c_match
,
541 module_i2c_driver(ht16k33_driver
);
543 MODULE_DESCRIPTION("Holtek HT16K33 driver");
544 MODULE_LICENSE("GPL");
545 MODULE_AUTHOR("Robin van der Gracht <robin@protonic.nl>");