linux/drivers/auxdisplay/ht16k33.c
<<
>>
Prefs
   1/*
   2 * HT16K33 driver
   3 *
   4 * Author: Robin van der Gracht <robin@protonic.nl>
   5 *
   6 * Copyright: (C) 2016 Protonic Holland.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope that it will be useful, but
  13 * WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * General Public License for more details.
  16 */
  17
  18#include <linux/kernel.h>
  19#include <linux/module.h>
  20#include <linux/interrupt.h>
  21#include <linux/i2c.h>
  22#include <linux/of.h>
  23#include <linux/fb.h>
  24#include <linux/slab.h>
  25#include <linux/backlight.h>
  26#include <linux/input.h>
  27#include <linux/input/matrix_keypad.h>
  28#include <linux/workqueue.h>
  29#include <linux/mm.h>
  30
  31/* Registers */
  32#define REG_SYSTEM_SETUP                0x20
  33#define REG_SYSTEM_SETUP_OSC_ON         BIT(0)
  34
  35#define REG_DISPLAY_SETUP               0x80
  36#define REG_DISPLAY_SETUP_ON            BIT(0)
  37
  38#define REG_ROWINT_SET                  0xA0
  39#define REG_ROWINT_SET_INT_EN           BIT(0)
  40#define REG_ROWINT_SET_INT_ACT_HIGH     BIT(1)
  41
  42#define REG_BRIGHTNESS                  0xE0
  43
  44/* Defines */
  45#define DRIVER_NAME                     "ht16k33"
  46
  47#define MIN_BRIGHTNESS                  0x1
  48#define MAX_BRIGHTNESS                  0x10
  49
  50#define HT16K33_MATRIX_LED_MAX_COLS     8
  51#define HT16K33_MATRIX_LED_MAX_ROWS     16
  52#define HT16K33_MATRIX_KEYPAD_MAX_COLS  3
  53#define HT16K33_MATRIX_KEYPAD_MAX_ROWS  12
  54
  55#define BYTES_PER_ROW           (HT16K33_MATRIX_LED_MAX_ROWS / 8)
  56#define HT16K33_FB_SIZE         (HT16K33_MATRIX_LED_MAX_COLS * BYTES_PER_ROW)
  57
  58struct ht16k33_keypad {
  59        struct i2c_client *client;
  60        struct input_dev *dev;
  61        uint32_t cols;
  62        uint32_t rows;
  63        uint32_t row_shift;
  64        uint32_t debounce_ms;
  65        uint16_t last_key_state[HT16K33_MATRIX_KEYPAD_MAX_COLS];
  66
  67        wait_queue_head_t wait;
  68        bool stopped;
  69};
  70
  71struct ht16k33_fbdev {
  72        struct fb_info *info;
  73        uint32_t refresh_rate;
  74        uint8_t *buffer;
  75        uint8_t *cache;
  76        struct delayed_work work;
  77};
  78
  79struct ht16k33_priv {
  80        struct i2c_client *client;
  81        struct ht16k33_keypad keypad;
  82        struct ht16k33_fbdev fbdev;
  83};
  84
  85static struct fb_fix_screeninfo ht16k33_fb_fix = {
  86        .id             = DRIVER_NAME,
  87        .type           = FB_TYPE_PACKED_PIXELS,
  88        .visual         = FB_VISUAL_MONO10,
  89        .xpanstep       = 0,
  90        .ypanstep       = 0,
  91        .ywrapstep      = 0,
  92        .line_length    = HT16K33_MATRIX_LED_MAX_ROWS,
  93        .accel          = FB_ACCEL_NONE,
  94};
  95
  96static struct fb_var_screeninfo ht16k33_fb_var = {
  97        .xres = HT16K33_MATRIX_LED_MAX_ROWS,
  98        .yres = HT16K33_MATRIX_LED_MAX_COLS,
  99        .xres_virtual = HT16K33_MATRIX_LED_MAX_ROWS,
 100        .yres_virtual = HT16K33_MATRIX_LED_MAX_COLS,
 101        .bits_per_pixel = 1,
 102        .red = { 0, 1, 0 },
 103        .green = { 0, 1, 0 },
 104        .blue = { 0, 1, 0 },
 105        .left_margin = 0,
 106        .right_margin = 0,
 107        .upper_margin = 0,
 108        .lower_margin = 0,
 109        .vmode = FB_VMODE_NONINTERLACED,
 110};
 111
 112static int ht16k33_display_on(struct ht16k33_priv *priv)
 113{
 114        uint8_t data = REG_DISPLAY_SETUP | REG_DISPLAY_SETUP_ON;
 115
 116        return i2c_smbus_write_byte(priv->client, data);
 117}
 118
 119static int ht16k33_display_off(struct ht16k33_priv *priv)
 120{
 121        return i2c_smbus_write_byte(priv->client, REG_DISPLAY_SETUP);
 122}
 123
 124static void ht16k33_fb_queue(struct ht16k33_priv *priv)
 125{
 126        struct ht16k33_fbdev *fbdev = &priv->fbdev;
 127
 128        schedule_delayed_work(&fbdev->work,
 129                              msecs_to_jiffies(HZ / fbdev->refresh_rate));
 130}
 131
 132/*
 133 * This gets the fb data from cache and copies it to ht16k33 display RAM
 134 */
 135static void ht16k33_fb_update(struct work_struct *work)
 136{
 137        struct ht16k33_fbdev *fbdev =
 138                container_of(work, struct ht16k33_fbdev, work.work);
 139        struct ht16k33_priv *priv =
 140                container_of(fbdev, struct ht16k33_priv, fbdev);
 141
 142        uint8_t *p1, *p2;
 143        int len, pos = 0, first = -1;
 144
 145        p1 = fbdev->cache;
 146        p2 = fbdev->buffer;
 147
 148        /* Search for the first byte with changes */
 149        while (pos < HT16K33_FB_SIZE && first < 0) {
 150                if (*(p1++) - *(p2++))
 151                        first = pos;
 152                pos++;
 153        }
 154
 155        /* No changes found */
 156        if (first < 0)
 157                goto requeue;
 158
 159        len = HT16K33_FB_SIZE - first;
 160        p1 = fbdev->cache + HT16K33_FB_SIZE - 1;
 161        p2 = fbdev->buffer + HT16K33_FB_SIZE - 1;
 162
 163        /* Determine i2c transfer length */
 164        while (len > 1) {
 165                if (*(p1--) - *(p2--))
 166                        break;
 167                len--;
 168        }
 169
 170        p1 = fbdev->cache + first;
 171        p2 = fbdev->buffer + first;
 172        if (!i2c_smbus_write_i2c_block_data(priv->client, first, len, p2))
 173                memcpy(p1, p2, len);
 174requeue:
 175        ht16k33_fb_queue(priv);
 176}
 177
 178static int ht16k33_initialize(struct ht16k33_priv *priv)
 179{
 180        uint8_t byte;
 181        int err;
 182        uint8_t data[HT16K33_MATRIX_LED_MAX_COLS * 2];
 183
 184        /* Clear RAM (8 * 16 bits) */
 185        memset(data, 0, sizeof(data));
 186        err = i2c_smbus_write_block_data(priv->client, 0, sizeof(data), data);
 187        if (err)
 188                return err;
 189
 190        /* Turn on internal oscillator */
 191        byte = REG_SYSTEM_SETUP_OSC_ON | REG_SYSTEM_SETUP;
 192        err = i2c_smbus_write_byte(priv->client, byte);
 193        if (err)
 194                return err;
 195
 196        /* Configure INT pin */
 197        byte = REG_ROWINT_SET | REG_ROWINT_SET_INT_ACT_HIGH;
 198        if (priv->client->irq > 0)
 199                byte |= REG_ROWINT_SET_INT_EN;
 200        return i2c_smbus_write_byte(priv->client, byte);
 201}
 202
 203static int ht16k33_bl_update_status(struct backlight_device *bl)
 204{
 205        int brightness = bl->props.brightness;
 206        struct ht16k33_priv *priv = bl_get_data(bl);
 207
 208        if (bl->props.power != FB_BLANK_UNBLANK ||
 209            bl->props.fb_blank != FB_BLANK_UNBLANK ||
 210            bl->props.state & BL_CORE_FBBLANK || brightness == 0) {
 211                return ht16k33_display_off(priv);
 212        }
 213
 214        ht16k33_display_on(priv);
 215        return i2c_smbus_write_byte(priv->client,
 216                                    REG_BRIGHTNESS | (brightness - 1));
 217}
 218
 219static int ht16k33_bl_check_fb(struct backlight_device *bl, struct fb_info *fi)
 220{
 221        struct ht16k33_priv *priv = bl_get_data(bl);
 222
 223        return (fi == NULL) || (fi->par == priv);
 224}
 225
 226static const struct backlight_ops ht16k33_bl_ops = {
 227        .update_status  = ht16k33_bl_update_status,
 228        .check_fb       = ht16k33_bl_check_fb,
 229};
 230
 231static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma)
 232{
 233        struct ht16k33_priv *priv = info->par;
 234
 235        return vm_insert_page(vma, vma->vm_start,
 236                              virt_to_page(priv->fbdev.buffer));
 237}
 238
 239static struct fb_ops ht16k33_fb_ops = {
 240        .owner = THIS_MODULE,
 241        .fb_read = fb_sys_read,
 242        .fb_write = fb_sys_write,
 243        .fb_fillrect = sys_fillrect,
 244        .fb_copyarea = sys_copyarea,
 245        .fb_imageblit = sys_imageblit,
 246        .fb_mmap = ht16k33_mmap,
 247};
 248
 249/*
 250 * This gets the keys from keypad and reports it to input subsystem.
 251 * Returns true if a key is pressed.
 252 */
 253static bool ht16k33_keypad_scan(struct ht16k33_keypad *keypad)
 254{
 255        const unsigned short *keycodes = keypad->dev->keycode;
 256        u16 new_state[HT16K33_MATRIX_KEYPAD_MAX_COLS];
 257        __le16 data[HT16K33_MATRIX_KEYPAD_MAX_COLS];
 258        unsigned long bits_changed;
 259        int row, col, code;
 260        int rc;
 261        bool pressed = false;
 262
 263        rc = i2c_smbus_read_i2c_block_data(keypad->client, 0x40,
 264                                           sizeof(data), (u8 *)data);
 265        if (rc != sizeof(data)) {
 266                dev_err(&keypad->client->dev,
 267                        "Failed to read key data, rc=%d\n", rc);
 268                return false;
 269        }
 270
 271        for (col = 0; col < keypad->cols; col++) {
 272                new_state[col] = le16_to_cpu(data[col]);
 273                if (new_state[col])
 274                        pressed = true;
 275                bits_changed = keypad->last_key_state[col] ^ new_state[col];
 276
 277                for_each_set_bit(row, &bits_changed, BITS_PER_LONG) {
 278                        code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
 279                        input_event(keypad->dev, EV_MSC, MSC_SCAN, code);
 280                        input_report_key(keypad->dev, keycodes[code],
 281                                         new_state[col] & BIT(row));
 282                }
 283        }
 284        input_sync(keypad->dev);
 285        memcpy(keypad->last_key_state, new_state, sizeof(u16) * keypad->cols);
 286
 287        return pressed;
 288}
 289
 290static irqreturn_t ht16k33_keypad_irq_thread(int irq, void *dev)
 291{
 292        struct ht16k33_keypad *keypad = dev;
 293
 294        do {
 295                wait_event_timeout(keypad->wait, keypad->stopped,
 296                                    msecs_to_jiffies(keypad->debounce_ms));
 297                if (keypad->stopped)
 298                        break;
 299        } while (ht16k33_keypad_scan(keypad));
 300
 301        return IRQ_HANDLED;
 302}
 303
 304static int ht16k33_keypad_start(struct input_dev *dev)
 305{
 306        struct ht16k33_keypad *keypad = input_get_drvdata(dev);
 307
 308        keypad->stopped = false;
 309        mb();
 310        enable_irq(keypad->client->irq);
 311
 312        return 0;
 313}
 314
 315static void ht16k33_keypad_stop(struct input_dev *dev)
 316{
 317        struct ht16k33_keypad *keypad = input_get_drvdata(dev);
 318
 319        keypad->stopped = true;
 320        mb();
 321        wake_up(&keypad->wait);
 322        disable_irq(keypad->client->irq);
 323}
 324
 325static int ht16k33_keypad_probe(struct i2c_client *client,
 326                                struct ht16k33_keypad *keypad)
 327{
 328        struct device_node *node = client->dev.of_node;
 329        u32 rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS;
 330        u32 cols = HT16K33_MATRIX_KEYPAD_MAX_COLS;
 331        int err;
 332
 333        keypad->client = client;
 334        init_waitqueue_head(&keypad->wait);
 335
 336        keypad->dev = devm_input_allocate_device(&client->dev);
 337        if (!keypad->dev)
 338                return -ENOMEM;
 339
 340        input_set_drvdata(keypad->dev, keypad);
 341
 342        keypad->dev->name = DRIVER_NAME"-keypad";
 343        keypad->dev->id.bustype = BUS_I2C;
 344        keypad->dev->open = ht16k33_keypad_start;
 345        keypad->dev->close = ht16k33_keypad_stop;
 346
 347        if (!of_get_property(node, "linux,no-autorepeat", NULL))
 348                __set_bit(EV_REP, keypad->dev->evbit);
 349
 350        err = of_property_read_u32(node, "debounce-delay-ms",
 351                                   &keypad->debounce_ms);
 352        if (err) {
 353                dev_err(&client->dev, "key debounce delay not specified\n");
 354                return err;
 355        }
 356
 357        err = matrix_keypad_parse_of_params(&client->dev, &rows, &cols);
 358        if (err)
 359                return err;
 360        if (rows > HT16K33_MATRIX_KEYPAD_MAX_ROWS ||
 361            cols > HT16K33_MATRIX_KEYPAD_MAX_COLS) {
 362                dev_err(&client->dev, "%u rows or %u cols out of range in DT\n",
 363                        rows, cols);
 364                return -ERANGE;
 365        }
 366
 367        keypad->rows = rows;
 368        keypad->cols = cols;
 369        keypad->row_shift = get_count_order(cols);
 370
 371        err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
 372                                         keypad->dev);
 373        if (err) {
 374                dev_err(&client->dev, "failed to build keymap\n");
 375                return err;
 376        }
 377
 378        err = devm_request_threaded_irq(&client->dev, client->irq,
 379                                        NULL, ht16k33_keypad_irq_thread,
 380                                        IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 381                                        DRIVER_NAME, keypad);
 382        if (err) {
 383                dev_err(&client->dev, "irq request failed %d, error %d\n",
 384                        client->irq, err);
 385                return err;
 386        }
 387
 388        ht16k33_keypad_stop(keypad->dev);
 389
 390        err = input_register_device(keypad->dev);
 391        if (err)
 392                return err;
 393
 394        return 0;
 395}
 396
 397static int ht16k33_probe(struct i2c_client *client,
 398                                  const struct i2c_device_id *id)
 399{
 400        int err;
 401        uint32_t dft_brightness;
 402        struct backlight_device *bl;
 403        struct backlight_properties bl_props;
 404        struct ht16k33_priv *priv;
 405        struct ht16k33_fbdev *fbdev;
 406        struct device_node *node = client->dev.of_node;
 407
 408        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 409                dev_err(&client->dev, "i2c_check_functionality error\n");
 410                return -EIO;
 411        }
 412
 413        if (client->irq <= 0) {
 414                dev_err(&client->dev, "No IRQ specified\n");
 415                return -EINVAL;
 416        }
 417
 418        priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
 419        if (!priv)
 420                return -ENOMEM;
 421
 422        priv->client = client;
 423        i2c_set_clientdata(client, priv);
 424        fbdev = &priv->fbdev;
 425
 426        err = ht16k33_initialize(priv);
 427        if (err)
 428                return err;
 429
 430        /* Framebuffer (2 bytes per column) */
 431        BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE);
 432        fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL);
 433        if (!fbdev->buffer)
 434                return -ENOMEM;
 435
 436        fbdev->cache = devm_kmalloc(&client->dev, HT16K33_FB_SIZE, GFP_KERNEL);
 437        if (!fbdev->cache) {
 438                err = -ENOMEM;
 439                goto err_fbdev_buffer;
 440        }
 441
 442        fbdev->info = framebuffer_alloc(0, &client->dev);
 443        if (!fbdev->info) {
 444                err = -ENOMEM;
 445                goto err_fbdev_buffer;
 446        }
 447
 448        err = of_property_read_u32(node, "refresh-rate-hz",
 449                &fbdev->refresh_rate);
 450        if (err) {
 451                dev_err(&client->dev, "refresh rate not specified\n");
 452                goto err_fbdev_info;
 453        }
 454        fb_bl_default_curve(fbdev->info, 0, MIN_BRIGHTNESS, MAX_BRIGHTNESS);
 455
 456        INIT_DELAYED_WORK(&fbdev->work, ht16k33_fb_update);
 457        fbdev->info->fbops = &ht16k33_fb_ops;
 458        fbdev->info->screen_base = (char __iomem *) fbdev->buffer;
 459        fbdev->info->screen_size = HT16K33_FB_SIZE;
 460        fbdev->info->fix = ht16k33_fb_fix;
 461        fbdev->info->var = ht16k33_fb_var;
 462        fbdev->info->pseudo_palette = NULL;
 463        fbdev->info->flags = FBINFO_FLAG_DEFAULT;
 464        fbdev->info->par = priv;
 465
 466        err = register_framebuffer(fbdev->info);
 467        if (err)
 468                goto err_fbdev_info;
 469
 470        err = ht16k33_keypad_probe(client, &priv->keypad);
 471        if (err)
 472                goto err_fbdev_unregister;
 473
 474        /* Backlight */
 475        memset(&bl_props, 0, sizeof(struct backlight_properties));
 476        bl_props.type = BACKLIGHT_RAW;
 477        bl_props.max_brightness = MAX_BRIGHTNESS;
 478
 479        bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl",
 480                                            &client->dev, priv,
 481                                            &ht16k33_bl_ops, &bl_props);
 482        if (IS_ERR(bl)) {
 483                dev_err(&client->dev, "failed to register backlight\n");
 484                err = PTR_ERR(bl);
 485                goto err_fbdev_unregister;
 486        }
 487
 488        err = of_property_read_u32(node, "default-brightness-level",
 489                                   &dft_brightness);
 490        if (err) {
 491                dft_brightness = MAX_BRIGHTNESS;
 492        } else if (dft_brightness > MAX_BRIGHTNESS) {
 493                dev_warn(&client->dev,
 494                         "invalid default brightness level: %u, using %u\n",
 495                         dft_brightness, MAX_BRIGHTNESS);
 496                dft_brightness = MAX_BRIGHTNESS;
 497        }
 498
 499        bl->props.brightness = dft_brightness;
 500        ht16k33_bl_update_status(bl);
 501
 502        ht16k33_fb_queue(priv);
 503        return 0;
 504
 505err_fbdev_unregister:
 506        unregister_framebuffer(fbdev->info);
 507err_fbdev_info:
 508        framebuffer_release(fbdev->info);
 509err_fbdev_buffer:
 510        free_page((unsigned long) fbdev->buffer);
 511
 512        return err;
 513}
 514
 515static int ht16k33_remove(struct i2c_client *client)
 516{
 517        struct ht16k33_priv *priv = i2c_get_clientdata(client);
 518        struct ht16k33_fbdev *fbdev = &priv->fbdev;
 519
 520        cancel_delayed_work(&fbdev->work);
 521        unregister_framebuffer(fbdev->info);
 522        framebuffer_release(fbdev->info);
 523        free_page((unsigned long) fbdev->buffer);
 524
 525        return 0;
 526}
 527
 528static const struct i2c_device_id ht16k33_i2c_match[] = {
 529        { "ht16k33", 0 },
 530        { }
 531};
 532MODULE_DEVICE_TABLE(i2c, ht16k33_i2c_match);
 533
 534static const struct of_device_id ht16k33_of_match[] = {
 535        { .compatible = "holtek,ht16k33", },
 536        { }
 537};
 538MODULE_DEVICE_TABLE(of, ht16k33_of_match);
 539
 540static struct i2c_driver ht16k33_driver = {
 541        .probe          = ht16k33_probe,
 542        .remove         = ht16k33_remove,
 543        .driver         = {
 544                .name           = DRIVER_NAME,
 545                .of_match_table = of_match_ptr(ht16k33_of_match),
 546        },
 547        .id_table = ht16k33_i2c_match,
 548};
 549module_i2c_driver(ht16k33_driver);
 550
 551MODULE_DESCRIPTION("Holtek HT16K33 driver");
 552MODULE_LICENSE("GPL");
 553MODULE_AUTHOR("Robin van der Gracht <robin@protonic.nl>");
 554