aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/fbtft/fbtft_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/fbtft/fbtft_device.c')
-rw-r--r--drivers/staging/fbtft/fbtft_device.c171
1 files changed, 113 insertions, 58 deletions
diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c
index fa916e88d549..071f79bd19f3 100644
--- a/drivers/staging/fbtft/fbtft_device.c
+++ b/drivers/staging/fbtft/fbtft_device.c
@@ -11,22 +11,18 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define pr_fmt(fmt) "fbtft_device: " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h>
+#include <video/mipi_display.h>
#include "fbtft.h"
-#define DRVNAME "fbtft_device"
-
#define MAX_GPIOS 32
static struct spi_device *spi_device;
@@ -115,7 +111,6 @@ module_param(verbose, uint, 0);
MODULE_PARM_DESC(verbose,
"0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
-
struct fbtft_device_display {
char *name;
struct spi_board_info *spi;
@@ -132,6 +127,59 @@ static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
"02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
"03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
+#define CBERRY28_GAMMA \
+ "D0 00 14 15 13 2C 42 43 4E 09 16 14 18 21\n" \
+ "D0 00 14 15 13 0B 43 55 53 0C 17 14 23 20"
+
+static int cberry28_init_sequence[] = {
+ /* turn off sleep mode */
+ -1, MIPI_DCS_EXIT_SLEEP_MODE,
+ -2, 120,
+
+ /* set pixel format to RGB-565 */
+ -1, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT,
+
+ -1, 0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33,
+
+ /*
+ * VGH = 13.26V
+ * VGL = -10.43V
+ */
+ -1, 0xB7, 0x35,
+
+ /*
+ * VDV and VRH register values come from command write
+ * (instead of NVM)
+ */
+ -1, 0xC2, 0x01, 0xFF,
+
+ /*
+ * VAP = 4.7V + (VCOM + VCOM offset + 0.5 * VDV)
+ * VAN = -4.7V + (VCOM + VCOM offset + 0.5 * VDV)
+ */
+ -1, 0xC3, 0x17,
+
+ /* VDV = 0V */
+ -1, 0xC4, 0x20,
+
+ /* VCOM = 0.675V */
+ -1, 0xBB, 0x17,
+
+ /* VCOM offset = 0V */
+ -1, 0xC5, 0x20,
+
+ /*
+ * AVDD = 6.8V
+ * AVCL = -4.8V
+ * VDS = 2.3V
+ */
+ -1, 0xD0, 0xA4, 0xA1,
+
+ -1, MIPI_DCS_SET_DISPLAY_ON,
+
+ -3,
+};
+
static int hy28b_init_sequence[] = {
-1, 0x00e7, 0x0010, -1, 0x0000, 0x0001,
-1, 0x0001, 0x0100, -1, 0x0002, 0x0700,
@@ -319,6 +367,27 @@ static struct fbtft_device_display displays[] = {
}
}
}, {
+ .name = "admatec_c-berry28",
+ .spi = &(struct spi_board_info) {
+ .modalias = "fb_st7789v",
+ .max_speed_hz = 48000000,
+ .mode = SPI_MODE_0,
+ .platform_data = &(struct fbtft_platform_data) {
+ .display = {
+ .buswidth = 8,
+ .backlight = 1,
+ .init_sequence = cberry28_init_sequence,
+ },
+ .gpios = (const struct fbtft_gpio []) {
+ { "reset", 25 },
+ { "dc", 22 },
+ { "led", 18 },
+ {},
+ },
+ .gamma = CBERRY28_GAMMA,
+ }
+ }
+ }, {
.name = "agm1264k-fl",
.pdev = &(struct platform_device) {
.name = "fb_agm1264k-fl",
@@ -1201,15 +1270,13 @@ static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
int xs, int ys, int xe, int ye)
{
- fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
- "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
write_reg(par, 0x2C);
}
/* used if gpios parameter is present */
-static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
+static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS + 1] = { };
static void fbtft_device_pdev_release(struct device *dev)
{
@@ -1222,16 +1289,16 @@ static int spi_device_found(struct device *dev, void *data)
{
struct spi_device *spi = container_of(dev, struct spi_device, dev);
- pr_info(DRVNAME": %s %s %dkHz %d bits mode=0x%02X\n",
- spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
- spi->bits_per_word, spi->mode);
+ dev_info(dev, "%s %s %dkHz %d bits mode=0x%02X\n", spi->modalias,
+ dev_name(dev), spi->max_speed_hz / 1000, spi->bits_per_word,
+ spi->mode);
return 0;
}
static void pr_spi_devices(void)
{
- pr_info(DRVNAME": SPI devices registered:\n");
+ pr_debug("SPI devices registered:\n");
bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
}
@@ -1241,16 +1308,15 @@ static int p_device_found(struct device *dev, void *data)
*pdev = container_of(dev, struct platform_device, dev);
if (strstr(pdev->name, "fb"))
- pr_info(DRVNAME": %s id=%d pdata? %s\n",
- pdev->name, pdev->id,
- pdev->dev.platform_data ? "yes" : "no");
+ dev_info(dev, "%s id=%d pdata? %s\n", pdev->name, pdev->id,
+ pdev->dev.platform_data ? "yes" : "no");
return 0;
}
static void pr_p_devices(void)
{
- pr_info(DRVNAME": 'fb' Platform devices registered:\n");
+ pr_debug("'fb' Platform devices registered:\n");
bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
}
@@ -1265,7 +1331,7 @@ static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
if (dev) {
if (verbose)
- pr_info(DRVNAME": Deleting %s\n", str);
+ dev_info(dev, "Deleting %s\n", str);
device_del(dev);
}
}
@@ -1276,8 +1342,8 @@ static int fbtft_device_spi_device_register(struct spi_board_info *spi)
master = spi_busnum_to_master(spi->bus_num);
if (!master) {
- pr_err(DRVNAME ": spi_busnum_to_master(%d) returned NULL\n",
- spi->bus_num);
+ pr_err("spi_busnum_to_master(%d) returned NULL\n",
+ spi->bus_num);
return -EINVAL;
}
/* make sure it's available */
@@ -1285,7 +1351,7 @@ static int fbtft_device_spi_device_register(struct spi_board_info *spi)
spi_device = spi_new_device(master, spi);
put_device(&master->dev);
if (!spi_device) {
- pr_err(DRVNAME ": spi_new_device() returned NULL\n");
+ dev_err(&master->dev, "spi_new_device() returned NULL\n");
return -EPERM;
}
return 0;
@@ -1308,11 +1374,9 @@ static int __init fbtft_device_init(void)
long val;
int ret = 0;
- pr_debug("\n\n"DRVNAME": init\n");
-
if (name == NULL) {
#ifdef MODULE
- pr_err(DRVNAME": missing module parameter: 'name'\n");
+ pr_err("missing module parameter: 'name'\n");
return -EINVAL;
#else
return 0;
@@ -1320,41 +1384,37 @@ static int __init fbtft_device_init(void)
}
if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
- pr_err(DRVNAME
- ": init parameter: exceeded max array size: %d\n",
- FBTFT_MAX_INIT_SEQUENCE);
+ pr_err("init parameter: exceeded max array size: %d\n",
+ FBTFT_MAX_INIT_SEQUENCE);
return -EINVAL;
}
/* parse module parameter: gpios */
while ((p_gpio = strsep(&gpios, ","))) {
if (strchr(p_gpio, ':') == NULL) {
- pr_err(DRVNAME
- ": error: missing ':' in gpios parameter: %s\n",
- p_gpio);
+ pr_err("error: missing ':' in gpios parameter: %s\n",
+ p_gpio);
return -EINVAL;
}
p_num = p_gpio;
p_name = strsep(&p_num, ":");
if (p_name == NULL || p_num == NULL) {
- pr_err(DRVNAME
- ": something bad happened parsing gpios parameter: %s\n",
- p_gpio);
+ pr_err("something bad happened parsing gpios parameter: %s\n",
+ p_gpio);
return -EINVAL;
}
ret = kstrtol(p_num, 10, &val);
if (ret) {
- pr_err(DRVNAME
- ": could not parse number in gpios parameter: %s:%s\n",
- p_name, p_num);
+ pr_err("could not parse number in gpios parameter: %s:%s\n",
+ p_name, p_num);
return -EINVAL;
}
- strcpy(fbtft_device_param_gpios[i].name, p_name);
+ strncpy(fbtft_device_param_gpios[i].name, p_name,
+ FBTFT_GPIO_NAME_SIZE - 1);
fbtft_device_param_gpios[i++].gpio = (int) val;
if (i == MAX_GPIOS) {
- pr_err(DRVNAME
- ": gpios parameter: exceeded max array size: %d\n",
- MAX_GPIOS);
+ pr_err("gpios parameter: exceeded max array size: %d\n",
+ MAX_GPIOS);
return -EINVAL;
}
}
@@ -1367,7 +1427,7 @@ static int __init fbtft_device_init(void)
if (verbose > 2)
pr_p_devices(); /* print list of 'fb' platform devices */
- pr_debug(DRVNAME": name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
+ pr_debug("name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
if (rotate > 0 && rotate < 4) {
rotate = (4 - rotate) * 90;
@@ -1381,11 +1441,11 @@ static int __init fbtft_device_init(void)
}
/* name=list lists all supported displays */
- if (strncmp(name, "list", 32) == 0) {
- pr_info(DRVNAME": Supported displays:\n");
+ if (strncmp(name, "list", FBTFT_GPIO_NAME_SIZE) == 0) {
+ pr_info("Supported displays:\n");
for (i = 0; i < ARRAY_SIZE(displays); i++)
- pr_info(DRVNAME": %s\n", displays[i].name);
+ pr_info("%s\n", displays[i].name);
return -ECANCELED;
}
@@ -1416,7 +1476,7 @@ static int __init fbtft_device_init(void)
p_device = displays[i].pdev;
pdata = p_device->dev.platform_data;
} else {
- pr_err(DRVNAME": broken displays array\n");
+ pr_err("broken displays array\n");
return -EINVAL;
}
@@ -1448,16 +1508,14 @@ static int __init fbtft_device_init(void)
if (displays[i].spi) {
ret = fbtft_device_spi_device_register(spi);
if (ret) {
- pr_err(DRVNAME
- ": failed to register SPI device\n");
+ pr_err("failed to register SPI device\n");
return ret;
}
} else {
ret = platform_device_register(p_device);
if (ret < 0) {
- pr_err(DRVNAME
- ": platform_device_register() returned %d\n",
- ret);
+ pr_err("platform_device_register() returned %d\n",
+ ret);
return ret;
}
}
@@ -1467,22 +1525,21 @@ static int __init fbtft_device_init(void)
}
if (!found) {
- pr_err(DRVNAME": display not supported: '%s'\n", name);
+ pr_err("display not supported: '%s'\n", name);
return -EINVAL;
}
if (verbose && pdata && pdata->gpios) {
gpio = pdata->gpios;
- pr_info(DRVNAME": GPIOS used by '%s':\n", name);
+ pr_info("GPIOS used by '%s':\n", name);
found = false;
while (verbose && gpio->name[0]) {
- pr_info(DRVNAME": '%s' = GPIO%d\n",
- gpio->name, gpio->gpio);
+ pr_info("'%s' = GPIO%d\n", gpio->name, gpio->gpio);
gpio++;
found = true;
}
if (!found)
- pr_info(DRVNAME": (none)\n");
+ pr_info("(none)\n");
}
if (spi_device && (verbose > 1))
@@ -1495,8 +1552,6 @@ static int __init fbtft_device_init(void)
static void __exit fbtft_device_exit(void)
{
- pr_debug(DRVNAME" - exit\n");
-
if (spi_device) {
device_del(&spi_device->dev);
kfree(spi_device);