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        u8 data[HT16K33_MATRIX_KEYPAD_MAX_COLS * 2];
 258        unsigned long bits_changed;
 259        int row, col, code;
 260        bool pressed = false;
 261
 262        if (i2c_smbus_read_i2c_block_data(keypad->client, 0x40, 6, data) != 6) {
 263                dev_err(&keypad->client->dev, "Failed to read key data\n");
 264                return false;
 265        }
 266
 267        for (col = 0; col < keypad->cols; col++) {
 268                new_state[col] = (data[col * 2 + 1] << 8) | data[col * 2];
 269                if (new_state[col])
 270                        pressed = true;
 271                bits_changed = keypad->last_key_state[col] ^ new_state[col];
 272
 273                for_each_set_bit(row, &bits_changed, BITS_PER_LONG) {
 274                        code = MATRIX_SCAN_CODE(row, col, keypad->row_shift);
 275                        input_event(keypad->dev, EV_MSC, MSC_SCAN, code);
 276                        input_report_key(keypad->dev, keycodes[code],
 277                                         new_state[col] & BIT(row));
 278                }
 279        }
 280        input_sync(keypad->dev);
 281        memcpy(keypad->last_key_state, new_state, sizeof(new_state));
 282
 283        return pressed;
 284}
 285
 286static irqreturn_t ht16k33_keypad_irq_thread(int irq, void *dev)
 287{
 288        struct ht16k33_keypad *keypad = dev;
 289
 290        do {
 291                wait_event_timeout(keypad->wait, keypad->stopped,
 292                                    msecs_to_jiffies(keypad->debounce_ms));
 293                if (keypad->stopped)
 294                        break;
 295        } while (ht16k33_keypad_scan(keypad));
 296
 297        return IRQ_HANDLED;
 298}
 299
 300static int ht16k33_keypad_start(struct input_dev *dev)
 301{
 302        struct ht16k33_keypad *keypad = input_get_drvdata(dev);
 303
 304        keypad->stopped = false;
 305        mb();
 306        enable_irq(keypad->client->irq);
 307
 308        return 0;
 309}
 310
 311static void ht16k33_keypad_stop(struct input_dev *dev)
 312{
 313        struct ht16k33_keypad *keypad = input_get_drvdata(dev);
 314
 315        keypad->stopped = true;
 316        mb();
 317        wake_up(&keypad->wait);
 318        disable_irq(keypad->client->irq);
 319}
 320
 321static int ht16k33_keypad_probe(struct i2c_client *client,
 322                                struct ht16k33_keypad *keypad)
 323{
 324        struct device_node *node = client->dev.of_node;
 325        u32 rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS;
 326        u32 cols = HT16K33_MATRIX_KEYPAD_MAX_COLS;
 327        int err;
 328
 329        keypad->client = client;
 330        init_waitqueue_head(&keypad->wait);
 331
 332        keypad->dev = devm_input_allocate_device(&client->dev);
 333        if (!keypad->dev)
 334                return -ENOMEM;
 335
 336        input_set_drvdata(keypad->dev, keypad);
 337
 338        keypad->dev->name = DRIVER_NAME"-keypad";
 339        keypad->dev->id.bustype = BUS_I2C;
 340        keypad->dev->open = ht16k33_keypad_start;
 341        keypad->dev->close = ht16k33_keypad_stop;
 342
 343        if (!of_get_property(node, "linux,no-autorepeat", NULL))
 344                __set_bit(EV_REP, keypad->dev->evbit);
 345
 346        err = of_property_read_u32(node, "debounce-delay-ms",
 347                                   &keypad->debounce_ms);
 348        if (err) {
 349                dev_err(&client->dev, "key debounce delay not specified\n");
 350                return err;
 351        }
 352
 353        err = matrix_keypad_parse_of_params(&client->dev, &rows, &cols);
 354        if (err)
 355                return err;
 356
 357        keypad->rows = rows;
 358        keypad->cols = cols;
 359        keypad->row_shift = get_count_order(cols);
 360
 361        err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
 362                                         keypad->dev);
 363        if (err) {
 364                dev_err(&client->dev, "failed to build keymap\n");
 365                return err;
 366        }
 367
 368        err = devm_request_threaded_irq(&client->dev, client->irq,
 369                                        NULL, ht16k33_keypad_irq_thread,
 370                                        IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 371                                        DRIVER_NAME, keypad);
 372        if (err) {
 373                dev_err(&client->dev, "irq request failed %d, error %d\n",
 374                        client->irq, err);
 375                return err;
 376        }
 377
 378        ht16k33_keypad_stop(keypad->dev);
 379
 380        err = input_register_device(keypad->dev);
 381        if (err)
 382                return err;
 383
 384        return 0;
 385}
 386
 387static int ht16k33_probe(struct i2c_client *client,
 388                                  const struct i2c_device_id *id)
 389{
 390        int err;
 391        uint32_t dft_brightness;
 392        struct backlight_device *bl;
 393        struct backlight_properties bl_props;
 394        struct ht16k33_priv *priv;
 395        struct ht16k33_fbdev *fbdev;
 396        struct device_node *node = client->dev.of_node;
 397
 398        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 399                dev_err(&client->dev, "i2c_check_functionality error\n");
 400                return -EIO;
 401        }
 402
 403        if (client->irq <= 0) {
 404                dev_err(&client->dev, "No IRQ specified\n");
 405                return -EINVAL;
 406        }
 407
 408        priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
 409        if (!priv)
 410                return -ENOMEM;
 411
 412        priv->client = client;
 413        i2c_set_clientdata(client, priv);
 414        fbdev = &priv->fbdev;
 415
 416        err = ht16k33_initialize(priv);
 417        if (err)
 418                return err;
 419
 420        /* Framebuffer (2 bytes per column) */
 421        BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE);
 422        fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL);
 423        if (!fbdev->buffer)
 424                return -ENOMEM;
 425
 426        fbdev->cache = devm_kmalloc(&client->dev, HT16K33_FB_SIZE, GFP_KERNEL);
 427        if (!fbdev->cache) {
 428                err = -ENOMEM;
 429                goto err_fbdev_buffer;
 430        }
 431
 432        fbdev->info = framebuffer_alloc(0, &client->dev);
 433        if (!fbdev->info) {
 434                err = -ENOMEM;
 435                goto err_fbdev_buffer;
 436        }
 437
 438        err = of_property_read_u32(node, "refresh-rate-hz",
 439                &fbdev->refresh_rate);
 440        if (err) {
 441                dev_err(&client->dev, "refresh rate not specified\n");
 442                goto err_fbdev_info;
 443        }
 444        fb_bl_default_curve(fbdev->info, 0, MIN_BRIGHTNESS, MAX_BRIGHTNESS);
 445
 446        INIT_DELAYED_WORK(&fbdev->work, ht16k33_fb_update);
 447        fbdev->info->fbops = &ht16k33_fb_ops;
 448        fbdev->info->screen_base = (char __iomem *) fbdev->buffer;
 449        fbdev->info->screen_size = HT16K33_FB_SIZE;
 450        fbdev->info->fix = ht16k33_fb_fix;
 451        fbdev->info->var = ht16k33_fb_var;
 452        fbdev->info->pseudo_palette = NULL;
 453        fbdev->info->flags = FBINFO_FLAG_DEFAULT;
 454        fbdev->info->par = priv;
 455
 456        err = register_framebuffer(fbdev->info);
 457        if (err)
 458                goto err_fbdev_info;
 459
 460        err = ht16k33_keypad_probe(client, &priv->keypad);
 461        if (err)
 462                goto err_fbdev_unregister;
 463
 464        /* Backlight */
 465        memset(&bl_props, 0, sizeof(struct backlight_properties));
 466        bl_props.type = BACKLIGHT_RAW;
 467        bl_props.max_brightness = MAX_BRIGHTNESS;
 468
 469        bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl",
 470                                            &client->dev, priv,
 471                                            &ht16k33_bl_ops, &bl_props);
 472        if (IS_ERR(bl)) {
 473                dev_err(&client->dev, "failed to register backlight\n");
 474                err = PTR_ERR(bl);
 475                goto err_fbdev_unregister;
 476        }
 477
 478        err = of_property_read_u32(node, "default-brightness-level",
 479                                   &dft_brightness);
 480        if (err) {
 481                dft_brightness = MAX_BRIGHTNESS;
 482        } else if (dft_brightness > MAX_BRIGHTNESS) {
 483                dev_warn(&client->dev,
 484                         "invalid default brightness level: %u, using %u\n",
 485                         dft_brightness, MAX_BRIGHTNESS);
 486                dft_brightness = MAX_BRIGHTNESS;
 487        }
 488
 489        bl->props.brightness = dft_brightness;
 490        ht16k33_bl_update_status(bl);
 491
 492        ht16k33_fb_queue(priv);
 493        return 0;
 494
 495err_fbdev_unregister:
 496        unregister_framebuffer(fbdev->info);
 497err_fbdev_info:
 498        framebuffer_release(fbdev->info);
 499err_fbdev_buffer:
 500        free_page((unsigned long) fbdev->buffer);
 501
 502        return err;
 503}
 504
 505static int ht16k33_remove(struct i2c_client *client)
 506{
 507        struct ht16k33_priv *priv = i2c_get_clientdata(client);
 508        struct ht16k33_fbdev *fbdev = &priv->fbdev;
 509
 510        cancel_delayed_work(&fbdev->work);
 511        unregister_framebuffer(fbdev->info);
 512        framebuffer_release(fbdev->info);
 513        free_page((unsigned long) fbdev->buffer);
 514
 515        return 0;
 516}
 517
 518static const struct i2c_device_id ht16k33_i2c_match[] = {
 519        { "ht16k33", 0 },
 520        { }
 521};
 522MODULE_DEVICE_TABLE(i2c, ht16k33_i2c_match);
 523
 524static const struct of_device_id ht16k33_of_match[] = {
 525        { .compatible = "holtek,ht16k33", },
 526        { }
 527};
 528MODULE_DEVICE_TABLE(of, ht16k33_of_match);
 529
 530static struct i2c_driver ht16k33_driver = {
 531        .probe          = ht16k33_probe,
 532        .remove         = ht16k33_remove,
 533        .driver         = {
 534                .name           = DRIVER_NAME,
 535                .of_match_table = of_match_ptr(ht16k33_of_match),
 536        },
 537        .id_table = ht16k33_i2c_match,
 538};
 539module_i2c_driver(ht16k33_driver);
 540
 541MODULE_DESCRIPTION("Holtek HT16K33 driver");
 542MODULE_LICENSE("GPL");
 543MODULE_AUTHOR("Robin van der Gracht <robin@protonic.nl>");
 544