linux/drivers/staging/fbtft/fb_st7735r.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * FB driver for the ST7735R LCD Controller
   4 *
   5 * Copyright (C) 2013 Noralf Tronnes
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/kernel.h>
  10#include <linux/init.h>
  11#include <video/mipi_display.h>
  12
  13#include "fbtft.h"
  14
  15#define DRVNAME "fb_st7735r"
  16#define DEFAULT_GAMMA   "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
  17                        "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
  18
  19static const s16 default_init_sequence[] = {
  20        -1, MIPI_DCS_SOFT_RESET,
  21        -2, 150,                               /* delay */
  22
  23        -1, MIPI_DCS_EXIT_SLEEP_MODE,
  24        -2, 500,                               /* delay */
  25
  26        /* FRMCTR1 - frame rate control: normal mode
  27         * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
  28         */
  29        -1, 0xB1, 0x01, 0x2C, 0x2D,
  30
  31        /* FRMCTR2 - frame rate control: idle mode
  32         * frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D)
  33         */
  34        -1, 0xB2, 0x01, 0x2C, 0x2D,
  35
  36        /* FRMCTR3 - frame rate control - partial mode
  37         * dot inversion mode, line inversion mode
  38         */
  39        -1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
  40
  41        /* INVCTR - display inversion control
  42         * no inversion
  43         */
  44        -1, 0xB4, 0x07,
  45
  46        /* PWCTR1 - Power Control
  47         * -4.6V, AUTO mode
  48         */
  49        -1, 0xC0, 0xA2, 0x02, 0x84,
  50
  51        /* PWCTR2 - Power Control
  52         * VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD
  53         */
  54        -1, 0xC1, 0xC5,
  55
  56        /* PWCTR3 - Power Control
  57         * Opamp current small, Boost frequency
  58         */
  59        -1, 0xC2, 0x0A, 0x00,
  60
  61        /* PWCTR4 - Power Control
  62         * BCLK/2, Opamp current small & Medium low
  63         */
  64        -1, 0xC3, 0x8A, 0x2A,
  65
  66        /* PWCTR5 - Power Control */
  67        -1, 0xC4, 0x8A, 0xEE,
  68
  69        /* VMCTR1 - Power Control */
  70        -1, 0xC5, 0x0E,
  71
  72        -1, MIPI_DCS_EXIT_INVERT_MODE,
  73
  74        -1, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT,
  75
  76        -1, MIPI_DCS_SET_DISPLAY_ON,
  77        -2, 100,                               /* delay */
  78
  79        -1, MIPI_DCS_ENTER_NORMAL_MODE,
  80        -2, 10,                               /* delay */
  81
  82        /* end marker */
  83        -3
  84};
  85
  86static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
  87{
  88        write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
  89                  xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
  90
  91        write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
  92                  ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
  93
  94        write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
  95}
  96
  97#define MY BIT(7)
  98#define MX BIT(6)
  99#define MV BIT(5)
 100static int set_var(struct fbtft_par *par)
 101{
 102        /* MADCTL - Memory data access control
 103         * RGB/BGR:
 104         * 1. Mode selection pin SRGB
 105         *    RGB H/W pin for color filter setting: 0=RGB, 1=BGR
 106         * 2. MADCTL RGB bit
 107         *    RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR
 108         */
 109        switch (par->info->var.rotate) {
 110        case 0:
 111                write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
 112                          MX | MY | (par->bgr << 3));
 113                break;
 114        case 270:
 115                write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
 116                          MY | MV | (par->bgr << 3));
 117                break;
 118        case 180:
 119                write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
 120                          par->bgr << 3);
 121                break;
 122        case 90:
 123                write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
 124                          MX | MV | (par->bgr << 3));
 125                break;
 126        }
 127
 128        return 0;
 129}
 130
 131/*
 132 * Gamma string format:
 133 * VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
 134 * VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
 135 */
 136#define CURVE(num, idx)  curves[(num) * par->gamma.num_values + (idx)]
 137static int set_gamma(struct fbtft_par *par, u32 *curves)
 138{
 139        int i, j;
 140
 141        /* apply mask */
 142        for (i = 0; i < par->gamma.num_curves; i++)
 143                for (j = 0; j < par->gamma.num_values; j++)
 144                        CURVE(i, j) &= 0x3f;
 145
 146        for (i = 0; i < par->gamma.num_curves; i++)
 147                write_reg(par, 0xE0 + i,
 148                          CURVE(i, 0),  CURVE(i, 1),
 149                          CURVE(i, 2),  CURVE(i, 3),
 150                          CURVE(i, 4),  CURVE(i, 5),
 151                          CURVE(i, 6),  CURVE(i, 7),
 152                          CURVE(i, 8),  CURVE(i, 9),
 153                          CURVE(i, 10), CURVE(i, 11),
 154                          CURVE(i, 12), CURVE(i, 13),
 155                          CURVE(i, 14), CURVE(i, 15));
 156
 157        return 0;
 158}
 159
 160#undef CURVE
 161
 162static struct fbtft_display display = {
 163        .regwidth = 8,
 164        .width = 128,
 165        .height = 160,
 166        .init_sequence = default_init_sequence,
 167        .gamma_num = 2,
 168        .gamma_len = 16,
 169        .gamma = DEFAULT_GAMMA,
 170        .fbtftops = {
 171                .set_addr_win = set_addr_win,
 172                .set_var = set_var,
 173                .set_gamma = set_gamma,
 174        },
 175};
 176
 177FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
 178
 179MODULE_ALIAS("spi:" DRVNAME);
 180MODULE_ALIAS("platform:" DRVNAME);
 181MODULE_ALIAS("spi:st7735r");
 182MODULE_ALIAS("platform:st7735r");
 183
 184MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
 185MODULE_AUTHOR("Noralf Tronnes");
 186MODULE_LICENSE("GPL");
 187