root/drivers/auxdisplay/ht16k33.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ht16k33_display_on
  2. ht16k33_display_off
  3. ht16k33_fb_queue
  4. ht16k33_fb_update
  5. ht16k33_initialize
  6. ht16k33_bl_update_status
  7. ht16k33_bl_check_fb
  8. ht16k33_mmap
  9. ht16k33_keypad_scan
  10. ht16k33_keypad_irq_thread
  11. ht16k33_keypad_start
  12. ht16k33_keypad_stop
  13. ht16k33_keypad_probe
  14. ht16k33_probe
  15. ht16k33_remove

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * HT16K33 driver
   4  *
   5  * Author: Robin van der Gracht <robin@protonic.nl>
   6  *
   7  * Copyright: (C) 2016 Protonic Holland.
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/module.h>
  12 #include <linux/interrupt.h>
  13 #include <linux/i2c.h>
  14 #include <linux/of.h>
  15 #include <linux/fb.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>
  21 #include <linux/mm.h>
  22 
  23 /* Registers */
  24 #define REG_SYSTEM_SETUP                0x20
  25 #define REG_SYSTEM_SETUP_OSC_ON         BIT(0)
  26 
  27 #define REG_DISPLAY_SETUP               0x80
  28 #define REG_DISPLAY_SETUP_ON            BIT(0)
  29 
  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)
  33 
  34 #define REG_BRIGHTNESS                  0xE0
  35 
  36 /* Defines */
  37 #define DRIVER_NAME                     "ht16k33"
  38 
  39 #define MIN_BRIGHTNESS                  0x1
  40 #define MAX_BRIGHTNESS                  0x10
  41 
  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
  46 
  47 #define BYTES_PER_ROW           (HT16K33_MATRIX_LED_MAX_ROWS / 8)
  48 #define HT16K33_FB_SIZE         (HT16K33_MATRIX_LED_MAX_COLS * BYTES_PER_ROW)
  49 
  50 struct ht16k33_keypad {
  51         struct i2c_client *client;
  52         struct input_dev *dev;
  53         uint32_t cols;
  54         uint32_t rows;
  55         uint32_t row_shift;
  56         uint32_t debounce_ms;
  57         uint16_t last_key_state[HT16K33_MATRIX_KEYPAD_MAX_COLS];
  58 
  59         wait_queue_head_t wait;
  60         bool stopped;
  61 };
  62 
  63 struct ht16k33_fbdev {
  64         struct fb_info *info;
  65         uint32_t refresh_rate;
  66         uint8_t *buffer;
  67         uint8_t *cache;
  68         struct delayed_work work;
  69 };
  70 
  71 struct ht16k33_priv {
  72         struct i2c_client *client;
  73         struct ht16k33_keypad keypad;
  74         struct ht16k33_fbdev fbdev;
  75 };
  76 
  77 static const struct fb_fix_screeninfo ht16k33_fb_fix = {
  78         .id             = DRIVER_NAME,
  79         .type           = FB_TYPE_PACKED_PIXELS,
  80         .visual         = FB_VISUAL_MONO10,
  81         .xpanstep       = 0,
  82         .ypanstep       = 0,
  83         .ywrapstep      = 0,
  84         .line_length    = HT16K33_MATRIX_LED_MAX_ROWS,
  85         .accel          = FB_ACCEL_NONE,
  86 };
  87 
  88 static const 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,
  93         .bits_per_pixel = 1,
  94         .red = { 0, 1, 0 },
  95         .green = { 0, 1, 0 },
  96         .blue = { 0, 1, 0 },
  97         .left_margin = 0,
  98         .right_margin = 0,
  99         .upper_margin = 0,
 100         .lower_margin = 0,
 101         .vmode = FB_VMODE_NONINTERLACED,
 102 };
 103 
 104 static int ht16k33_display_on(struct ht16k33_priv *priv)
 105 {
 106         uint8_t data = REG_DISPLAY_SETUP | REG_DISPLAY_SETUP_ON;
 107 
 108         return i2c_smbus_write_byte(priv->client, data);
 109 }
 110 
 111 static int ht16k33_display_off(struct ht16k33_priv *priv)
 112 {
 113         return i2c_smbus_write_byte(priv->client, REG_DISPLAY_SETUP);
 114 }
 115 
 116 static void ht16k33_fb_queue(struct ht16k33_priv *priv)
 117 {
 118         struct ht16k33_fbdev *fbdev = &priv->fbdev;
 119 
 120         schedule_delayed_work(&fbdev->work,
 121                               msecs_to_jiffies(HZ / fbdev->refresh_rate));
 122 }
 123 
 124 /*
 125  * This gets the fb data from cache and copies it to ht16k33 display RAM
 126  */
 127 static void ht16k33_fb_update(struct work_struct *work)
 128 {
 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);
 133 
 134         uint8_t *p1, *p2;
 135         int len, pos = 0, first = -1;
 136 
 137         p1 = fbdev->cache;
 138         p2 = fbdev->buffer;
 139 
 140         /* Search for the first byte with changes */
 141         while (pos < HT16K33_FB_SIZE && first < 0) {
 142                 if (*(p1++) - *(p2++))
 143                         first = pos;
 144                 pos++;
 145         }
 146 
 147         /* No changes found */
 148         if (first < 0)
 149                 goto requeue;
 150 
 151         len = HT16K33_FB_SIZE - first;
 152         p1 = fbdev->cache + HT16K33_FB_SIZE - 1;
 153         p2 = fbdev->buffer + HT16K33_FB_SIZE - 1;
 154 
 155         /* Determine i2c transfer length */
 156         while (len > 1) {
 157                 if (*(p1--) - *(p2--))
 158                         break;
 159                 len--;
 160         }
 161 
 162         p1 = fbdev->cache + first;
 163         p2 = fbdev->buffer + first;
 164         if (!i2c_smbus_write_i2c_block_data(priv->client, first, len, p2))
 165                 memcpy(p1, p2, len);
 166 requeue:
 167         ht16k33_fb_queue(priv);
 168 }
 169 
 170 static int ht16k33_initialize(struct ht16k33_priv *priv)
 171 {
 172         uint8_t byte;
 173         int err;
 174         uint8_t data[HT16K33_MATRIX_LED_MAX_COLS * 2];
 175 
 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);
 179         if (err)
 180                 return err;
 181 
 182         /* Turn on internal oscillator */
 183         byte = REG_SYSTEM_SETUP_OSC_ON | REG_SYSTEM_SETUP;
 184         err = i2c_smbus_write_byte(priv->client, byte);
 185         if (err)
 186                 return err;
 187 
 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);
 193 }
 194 
 195 static int ht16k33_bl_update_status(struct backlight_device *bl)
 196 {
 197         int brightness = bl->props.brightness;
 198         struct ht16k33_priv *priv = bl_get_data(bl);
 199 
 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);
 204         }
 205 
 206         ht16k33_display_on(priv);
 207         return i2c_smbus_write_byte(priv->client,
 208                                     REG_BRIGHTNESS | (brightness - 1));
 209 }
 210 
 211 static int ht16k33_bl_check_fb(struct backlight_device *bl, struct fb_info *fi)
 212 {
 213         struct ht16k33_priv *priv = bl_get_data(bl);
 214 
 215         return (fi == NULL) || (fi->par == priv);
 216 }
 217 
 218 static const struct backlight_ops ht16k33_bl_ops = {
 219         .update_status  = ht16k33_bl_update_status,
 220         .check_fb       = ht16k33_bl_check_fb,
 221 };
 222 
 223 static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma)
 224 {
 225         struct ht16k33_priv *priv = info->par;
 226         struct page *pages = virt_to_page(priv->fbdev.buffer);
 227 
 228         return vm_map_pages_zero(vma, &pages, 1);
 229 }
 230 
 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,
 239 };
 240 
 241 /*
 242  * This gets the keys from keypad and reports it to input subsystem.
 243  * Returns true if a key is pressed.
 244  */
 245 static bool ht16k33_keypad_scan(struct ht16k33_keypad *keypad)
 246 {
 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;
 251         int row, col, code;
 252         int rc;
 253         bool pressed = false;
 254 
 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);
 260                 return false;
 261         }
 262 
 263         for (col = 0; col < keypad->cols; col++) {
 264                 new_state[col] = le16_to_cpu(data[col]);
 265                 if (new_state[col])
 266                         pressed = true;
 267                 bits_changed = keypad->last_key_state[col] ^ new_state[col];
 268 
 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));
 274                 }
 275         }
 276         input_sync(keypad->dev);
 277         memcpy(keypad->last_key_state, new_state, sizeof(u16) * keypad->cols);
 278 
 279         return pressed;
 280 }
 281 
 282 static irqreturn_t ht16k33_keypad_irq_thread(int irq, void *dev)
 283 {
 284         struct ht16k33_keypad *keypad = dev;
 285 
 286         do {
 287                 wait_event_timeout(keypad->wait, keypad->stopped,
 288                                     msecs_to_jiffies(keypad->debounce_ms));
 289                 if (keypad->stopped)
 290                         break;
 291         } while (ht16k33_keypad_scan(keypad));
 292 
 293         return IRQ_HANDLED;
 294 }
 295 
 296 static int ht16k33_keypad_start(struct input_dev *dev)
 297 {
 298         struct ht16k33_keypad *keypad = input_get_drvdata(dev);
 299 
 300         keypad->stopped = false;
 301         mb();
 302         enable_irq(keypad->client->irq);
 303 
 304         return 0;
 305 }
 306 
 307 static void ht16k33_keypad_stop(struct input_dev *dev)
 308 {
 309         struct ht16k33_keypad *keypad = input_get_drvdata(dev);
 310 
 311         keypad->stopped = true;
 312         mb();
 313         wake_up(&keypad->wait);
 314         disable_irq(keypad->client->irq);
 315 }
 316 
 317 static int ht16k33_keypad_probe(struct i2c_client *client,
 318                                 struct ht16k33_keypad *keypad)
 319 {
 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;
 323         int err;
 324 
 325         keypad->client = client;
 326         init_waitqueue_head(&keypad->wait);
 327 
 328         keypad->dev = devm_input_allocate_device(&client->dev);
 329         if (!keypad->dev)
 330                 return -ENOMEM;
 331 
 332         input_set_drvdata(keypad->dev, keypad);
 333 
 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;
 338 
 339         if (!of_get_property(node, "linux,no-autorepeat", NULL))
 340                 __set_bit(EV_REP, keypad->dev->evbit);
 341 
 342         err = of_property_read_u32(node, "debounce-delay-ms",
 343                                    &keypad->debounce_ms);
 344         if (err) {
 345                 dev_err(&client->dev, "key debounce delay not specified\n");
 346                 return err;
 347         }
 348 
 349         err = matrix_keypad_parse_of_params(&client->dev, &rows, &cols);
 350         if (err)
 351                 return err;
 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",
 355                         rows, cols);
 356                 return -ERANGE;
 357         }
 358 
 359         keypad->rows = rows;
 360         keypad->cols = cols;
 361         keypad->row_shift = get_count_order(cols);
 362 
 363         err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
 364                                          keypad->dev);
 365         if (err) {
 366                 dev_err(&client->dev, "failed to build keymap\n");
 367                 return err;
 368         }
 369 
 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);
 374         if (err) {
 375                 dev_err(&client->dev, "irq request failed %d, error %d\n",
 376                         client->irq, err);
 377                 return err;
 378         }
 379 
 380         ht16k33_keypad_stop(keypad->dev);
 381 
 382         err = input_register_device(keypad->dev);
 383         if (err)
 384                 return err;
 385 
 386         return 0;
 387 }
 388 
 389 static int ht16k33_probe(struct i2c_client *client,
 390                                   const struct i2c_device_id *id)
 391 {
 392         int err;
 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;
 399 
 400         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 401                 dev_err(&client->dev, "i2c_check_functionality error\n");
 402                 return -EIO;
 403         }
 404 
 405         if (client->irq <= 0) {
 406                 dev_err(&client->dev, "No IRQ specified\n");
 407                 return -EINVAL;
 408         }
 409 
 410         priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
 411         if (!priv)
 412                 return -ENOMEM;
 413 
 414         priv->client = client;
 415         i2c_set_clientdata(client, priv);
 416         fbdev = &priv->fbdev;
 417 
 418         err = ht16k33_initialize(priv);
 419         if (err)
 420                 return err;
 421 
 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);
 425         if (!fbdev->buffer)
 426                 return -ENOMEM;
 427 
 428         fbdev->cache = devm_kmalloc(&client->dev, HT16K33_FB_SIZE, GFP_KERNEL);
 429         if (!fbdev->cache) {
 430                 err = -ENOMEM;
 431                 goto err_fbdev_buffer;
 432         }
 433 
 434         fbdev->info = framebuffer_alloc(0, &client->dev);
 435         if (!fbdev->info) {
 436                 err = -ENOMEM;
 437                 goto err_fbdev_buffer;
 438         }
 439 
 440         err = of_property_read_u32(node, "refresh-rate-hz",
 441                 &fbdev->refresh_rate);
 442         if (err) {
 443                 dev_err(&client->dev, "refresh rate not specified\n");
 444                 goto err_fbdev_info;
 445         }
 446         fb_bl_default_curve(fbdev->info, 0, MIN_BRIGHTNESS, MAX_BRIGHTNESS);
 447 
 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;
 457 
 458         err = register_framebuffer(fbdev->info);
 459         if (err)
 460                 goto err_fbdev_info;
 461 
 462         err = ht16k33_keypad_probe(client, &priv->keypad);
 463         if (err)
 464                 goto err_fbdev_unregister;
 465 
 466         /* Backlight */
 467         memset(&bl_props, 0, sizeof(struct backlight_properties));
 468         bl_props.type = BACKLIGHT_RAW;
 469         bl_props.max_brightness = MAX_BRIGHTNESS;
 470 
 471         bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl",
 472                                             &client->dev, priv,
 473                                             &ht16k33_bl_ops, &bl_props);
 474         if (IS_ERR(bl)) {
 475                 dev_err(&client->dev, "failed to register backlight\n");
 476                 err = PTR_ERR(bl);
 477                 goto err_fbdev_unregister;
 478         }
 479 
 480         err = of_property_read_u32(node, "default-brightness-level",
 481                                    &dft_brightness);
 482         if (err) {
 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;
 489         }
 490 
 491         bl->props.brightness = dft_brightness;
 492         ht16k33_bl_update_status(bl);
 493 
 494         ht16k33_fb_queue(priv);
 495         return 0;
 496 
 497 err_fbdev_unregister:
 498         unregister_framebuffer(fbdev->info);
 499 err_fbdev_info:
 500         framebuffer_release(fbdev->info);
 501 err_fbdev_buffer:
 502         free_page((unsigned long) fbdev->buffer);
 503 
 504         return err;
 505 }
 506 
 507 static int ht16k33_remove(struct i2c_client *client)
 508 {
 509         struct ht16k33_priv *priv = i2c_get_clientdata(client);
 510         struct ht16k33_fbdev *fbdev = &priv->fbdev;
 511 
 512         cancel_delayed_work_sync(&fbdev->work);
 513         unregister_framebuffer(fbdev->info);
 514         framebuffer_release(fbdev->info);
 515         free_page((unsigned long) fbdev->buffer);
 516 
 517         return 0;
 518 }
 519 
 520 static const struct i2c_device_id ht16k33_i2c_match[] = {
 521         { "ht16k33", 0 },
 522         { }
 523 };
 524 MODULE_DEVICE_TABLE(i2c, ht16k33_i2c_match);
 525 
 526 static const struct of_device_id ht16k33_of_match[] = {
 527         { .compatible = "holtek,ht16k33", },
 528         { }
 529 };
 530 MODULE_DEVICE_TABLE(of, ht16k33_of_match);
 531 
 532 static struct i2c_driver ht16k33_driver = {
 533         .probe          = ht16k33_probe,
 534         .remove         = ht16k33_remove,
 535         .driver         = {
 536                 .name           = DRIVER_NAME,
 537                 .of_match_table = of_match_ptr(ht16k33_of_match),
 538         },
 539         .id_table = ht16k33_i2c_match,
 540 };
 541 module_i2c_driver(ht16k33_driver);
 542 
 543 MODULE_DESCRIPTION("Holtek HT16K33 driver");
 544 MODULE_LICENSE("GPL");
 545 MODULE_AUTHOR("Robin van der Gracht <robin@protonic.nl>");

/* [<][>][^][v][top][bottom][index][help] */