/* * ========================================================================== * * Filename: lcd-spi.c * * Description: * * Version: 0.01 * Created: Thursday, December 27, 2012 02:50:05 HKT * * Author: Sam Mei (), * Company: * * ========================================================================== */ #include <common.h> #include <command.h> #include <asm/types.h> #include <asm/errno.h> #include <asm/byteorder.h> #include "../../../board/wmt/include/wmt_spi.h" #include "../../../board/wmt/include/wmt_iomux.h" #include "../lcd.h" #define CHIPSELECT 0 #ifndef SPI_GPIO static void spi_ctrl_9bit_tx(u8 val, int cmd_data) { uint8_t buf[2],rbuf[2]; if (cmd_data) buf[0] = (val >> 1) | BIT7; else buf[0] = (val >> 1) & 0x7f; buf[1] = (val << 7); spi_write_then_read_data(buf, rbuf, sizeof(buf), SPI_MODE_1, CHIPSELECT); } #else #define CLK WMT_PIN_GP12_SPI0CLK #define MOSI WMT_PIN_GP12_SPI0MOSI #define MISO WMT_PIN_GP12_SPI0MISO #define SS WMT_PIN_GP12_SPI0SS0 static void spi_gpio_9bit_tx(u8 val, int cmd_data) { int i; // CS gpio_direction_output(SS, 1); gpio_direction_output(SS, 0); // D/C gpio_direction_output(MOSI, cmd_data); gpio_direction_output(CLK, 0); gpio_direction_output(CLK, 1); // 8-bit value for (i = 7; i >= 0; i--) { gpio_direction_output(MOSI, !!(val & (1 << i))); gpio_direction_output(CLK, 0); gpio_direction_output(CLK, 1); } // CS gpio_direction_output(SS, 1); } #endif static inline void spi_9bit_tx(u8 val, int cmd_data) { #ifdef SPI_GPIO spi_gpio_9bit_tx(val, cmd_data); #else spi_ctrl_9bit_tx(val, cmd_data); #endif } static int ts8224b_cmd(u8 cmd) { spi_9bit_tx(cmd, 0); return 0; } static int ts8224b_data(u8 data) { spi_9bit_tx(data, 1); return 0; } /* * setenv wmt.lcd.setup 0 * setenv wmt.display.param 2:0:24:1024:600:60 * setenv wmt.display.tmr 30000:0:78:78:480:78:4:60:800:60 */ static int ts8224b_init(void) { static uint16_t settings[] = { #include "ts8224b.h" }; int i; printf(" ## %s \n", __FUNCTION__); for (i = 0; i < ARRAY_SIZE(settings); i += 2) { ts8224b_cmd(settings[i] >> 8); ts8224b_data(settings[i+1]); } ts8224b_cmd(0x11); mdelay(120); ts8224b_cmd(0x29); mdelay(50); ts8224b_cmd(0x2c); return 0; } static int i2c_write(int i2c_idx, uint8_t reg, uint8_t value) { unsigned char data[2] = { reg, value }; struct i2c_msg_s msg[1] = { { .addr = 0xE0 >> 1, .flags = I2C_M_WR, .len = 2, .buf = data, }, }; if (wmt_i2c_transfer(&msg[0], 1, i2c_idx) > 0) return 0; printf(" ## lcd i2c1 write error %s, %d\n", __func__, __LINE__); return -1; } static uint8_t init_data[] = { 0x4b, 0x01, 0x0c, 0x01, 0x05, 0x03, 0x41, 0x03, 0x10, 0x06, 0x11, 0xE0, 0x12, 0x00, 0x13, 0x3C, 0x14, 0x06, 0x15, 0x40, 0x16, 0x03, 0x17, 0x9E, 0x18, 0x00, 0x19, 0x10, 0x1a, 0x03, 0x1b, 0x84, 0x1c, 0x80, 0x1d, 0x0A, 0x1e, 0x80, 0x1f, 0x06, 0x3c, 0x17, 0x3e, 0x16, 0x36, 0x00, 0x31, 0x00, 0x35, 0x41, 0x30, 0xB0, 0x30, 0xB1, 0x00, 0x0B, }; static int chunghwa_init(void) { int i; printf(" ## %s, %d\n", __FUNCTION__, __LINE__); for (i = 0; i < ARRAY_SIZE(init_data); i += 2) { i2c_write(1, init_data[i], init_data[i+1]); } return 0; } enum { LCD_SETUP_TS8224B, LCD_SETUP_CHUNGHWA, LCD_SETUP_MAX, }; int lcd_spi_setup(void) { int id; char *s = getenv("wmt.lcd.setup"); if (!s) return -ENODEV; id = simple_strtoul(s, NULL, 10); switch (id) { case LCD_SETUP_TS8224B: return ts8224b_init(); case LCD_SETUP_CHUNGHWA: return chunghwa_init(); default: return -EINVAL; } }