( ICN6211 ILI9806E + 模拟SPI+模拟I2C )

/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 and* only version 2 as published by the Free Software Foundation.** This program is distributed in the hope that it will be useful,* 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.** * version:1.0* data:2017.9.9* function description : mipi-2-rgb (icn6211) device driver which tranfer msg via i2c**/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/mdss_io_util.h>
#include <linux/slab.h>struct icn6211 {int en_gp;int lcd_rst_gp;unsigned char slave_addr;int iic_scl_gp;int iic_sda_gp;int spi_sdi_gp;int spi_sdo_gp;int spi_csx_gp;int spi_sck_gp;int rgb_or_lvds; /* 1:rgb, 0, lvds */struct mutex icn6211_mutex;
};struct init_cmd {char reg_add;char reg_val;
};static const struct init_cmd icn6211_cmd_table[] = {#if 0{0x20, 0x20},{0x21, 0xE0},{0x22, 0x13},{0x23, 0xA0},{0x24, 0x30},{0x25, 0x28},{0x26, 0x00},{0x27, 0x0D},{0x28, 0x03},{0x29, 0x1D},{0x34, 0x80},{0x36, 0xA0},{0x86, 0x29},{0xB5, 0xA0},{0x5C, 0xFF},{0x2A, 0x01},{0x56, 0x90},{0x6B, 0x71},{0x69, 0x2B},{0x10, 0x45},{0x11, 0x88},{0xB6, 0x20},{0x51, 0x20},{0x14, 0x43},{0x2a, 0x49},{0x09, 0x10}
#endif{0x20, 0xE0},{0x21, 0x20},{0x22, 0x31},{0x23, 0x2E},{0x24, 0x04},{0x25, 0x2C},{0x26, 0x00},{0x27, 0x0F},{0x28, 0x01},{0x29, 0x10},{0x34, 0x80},{0x36, 0x2E},{0x86, 0x29},{0xB5, 0xA0},{0x5C, 0xFF},{0x2A, 0x01},{0x56, 0x90},{0x6B, 0x71},{0x69, 0x24},{0x10, 0xC0},{0x11, 0x88},{0xB6, 0x20},{0x51, 0x20},{0x14, 0x43},{0x2a, 0x49},{0x09, 0x10}
};#define ICN6211_CMD_CNT (sizeof(icn6211_cmd_table)/sizeof(icn6211_cmd_table[0]))static struct icn6211 *icn6211_pdata = NULL;/*simulated i2c ----begin*/
#define OUTP 1
#define INP 0
#define SDA (icn6211_pdata->iic_sda_gp)
#define SCL (icn6211_pdata->iic_scl_gp)#define  gpio_set_direction(fuck1,fuck2) {if(fuck2==1)gpio_direction_output(fuck1,0);else gpio_direction_input(fuck1);}
#define  gpio_set_val(fuck1,fuck2)       gpio_direction_output(fuck1,fuck2)
#define  gpio_status(fuck1)              gpio_get_value(fuck1)static int i2c_start(void)
{gpio_set_direction(SDA, OUTP);gpio_set_direction (SCL, OUTP);gpio_set_val(SCL, 1);udelay(50);gpio_set_val(SDA, 1);udelay(50);gpio_set_val(SDA, 0);udelay(50);gpio_set_val(SCL, 0);udelay(50);return 0 ;
}static void i2c_stop(void)
{gpio_set_val(SCL, 0);udelay(50);gpio_set_direction(SDA, OUTP);gpio_set_val(SDA, 0);udelay(50);gpio_set_val(SCL, 1);udelay(50);gpio_set_val(SDA, 1);udelay(50);
}static unsigned char i2c_read_ack(void)
{unsigned char r;gpio_set_direction(SDA, INP);gpio_set_val(SCL,1);udelay(50);r = gpio_status(SDA);udelay(50);gpio_set_val(SCL,0);udelay(50);return r;
}#if 0
static int i2c_send_ack(void)
{gpio_set_direction(SDA, OUTP);gpio_set_val(SDA, 0);udelay(50);gpio_set_val(SCL,1);udelay(50);gpio_set_val(SCL,0);udelay(50);return 0 ;
}
#endifstatic int i2c_send_noack(void)
{gpio_set_direction(SDA, OUTP);gpio_set_val(SDA, 1);udelay(50);gpio_set_val(SCL,1);udelay(50);gpio_set_val(SCL,0);udelay(50);return 0 ;
}
/* I2C write */
static void i2c_write_byte(unsigned char b)
{int i;gpio_set_direction(SDA, OUTP);for (i=7; i>=0; i--) {udelay(50);gpio_set_val(SDA, !!(b & (1<<i)));udelay(50);gpio_set_val(SCL, 1);udelay(50);gpio_set_val(SCL, 0);}udelay(50);
}
/* I2C read */
unsigned char i2c_read_byte(void)
{int i;unsigned char r = 0;gpio_set_direction(SDA, INP);for (i=7; i>=0; i--) {gpio_set_val(SCL, 1);udelay(50);r = (r <<1) | gpio_status(SDA);gpio_set_val(SCL, 0);udelay(50);}//i2c_send_ack();return r;
}static int icn6211_i2c_write_byte(struct icn6211 *pdata, char addr, char val)
{/*i2c_smbus_write_byte_data()*/unsigned char t;unsigned char slave_addr = pdata->slave_addr;i2c_start();t = (slave_addr << 1) | 0;i2c_write_byte(t);i2c_read_ack();i2c_write_byte(addr);i2c_read_ack();i2c_write_byte(val);i2c_read_ack();i2c_stop();return 0;
}static int icn6211_i2c_read_byte(struct icn6211 *pdata, char addr)
{/*i2c_smbus_read_byte_data()*/unsigned char t,val;unsigned char slave_addr = pdata->slave_addr;i2c_start();t = (slave_addr << 1) | 0;i2c_write_byte(t);i2c_read_ack();i2c_write_byte(addr);i2c_read_ack();i2c_start();t = (slave_addr << 1) | 1;i2c_write_byte(t);i2c_read_ack();val = i2c_read_byte();i2c_send_noack();i2c_stop();return val ;
}static int icn6211_init(struct icn6211 *pdata)
{int rc = 0;int i = 0;const struct init_cmd *cmd_list = icn6211_cmd_table;mutex_lock(&pdata->icn6211_mutex);if (pdata) {for (i = 0; i < ICN6211_CMD_CNT; i++){pr_info("ICN6211 write: reg_add=0x%X, reg_val=0x%X\n",(cmd_list+i)->reg_add, (cmd_list+i)->reg_val);rc = icn6211_i2c_write_byte(pdata, (cmd_list+i)->reg_add, (cmd_list+i)->reg_val);if (rc < 0) {mutex_unlock(&pdata->icn6211_mutex);return rc;}}}mutex_unlock(&pdata->icn6211_mutex);return rc;
}static int icn6211_dump(struct icn6211 *pdata)
{int rc = 0;int i = 0;const struct init_cmd *cmd_list = icn6211_cmd_table;mutex_lock(&pdata->icn6211_mutex);if (pdata) {for (i = 0; i < ICN6211_CMD_CNT; i++){rc = icn6211_i2c_read_byte(pdata, (cmd_list+i)->reg_add);if (rc < 0) {mutex_unlock(&pdata->icn6211_mutex);return rc;}pr_info("ICN6211 read : reg_add=0x%X, reg_val=0x%X\n",(cmd_list+i)->reg_add, rc);}rc = icn6211_i2c_read_byte(pdata, 0x00);pr_info("ICN6211 read : reg_add=0x00, reg_val=0x%X\n", rc);}mutex_unlock(&pdata->icn6211_mutex);return rc;
}
/*simulated i2c ----end*//*simulated spi ----begin*/
#define SPI_SDI(x)  gpio_direction_output(icn6211_pdata->spi_sdi_gp, x)
#define SPI_SDO     gpio_get_value(icn6211_pdata->spi_sdo_gp)
#define SPI_SCK(x)  gpio_direction_output(icn6211_pdata->spi_sck_gp, x)
#define SPI_SCS(x)  gpio_direction_output(icn6211_pdata->spi_csx_gp, x)
#define DelayNs(x)  ndelay(x)static int spi_write_byte(unsigned char input)
{int i = 0;SPI_SCS(0);DelayNs(50);SPI_SDI(1);SPI_SCK(0);DelayNs(50);SPI_SCK(1);DelayNs(50);for(i = 0; i < 8; i++) {SPI_SCK(0);if (input & 0x80) {SPI_SDI(1);} else {SPI_SDI(0);}DelayNs(50);SPI_SCK(1);input <<= 1;}return 0;
}static int spi_read_byte(void)
{int i = 0;int data = 0;SPI_SCS(0);DelayNs(150);for (i = 0; i < 8; i++) {data <<= 1;SPI_SCK(0);DelayNs(150);SPI_SCK(1);data |= SPI_SDO;DelayNs(50);}return data;
}static int SPI_WriteCmd(unsigned char cmd)
{return spi_write_byte(cmd);
}static int SPI_WriteDat(unsigned char dat)
{return spi_write_byte(dat);
}static int lcd_read_dat(void)
{return spi_read_byte();
}
/*simulated spi ----end*//*lcd init cmd ---- begin*/
#define RESET_LCD(x)    gpio_direction_output(icn6211_pdata->lcd_rst_gp, x)
#define DelayMs(x)      mdelay(x)static void lcd_init(void)
{pr_info("icn6211 lcd_init\n");RESET_LCD(1);DelayMs(10);RESET_LCD(0);DelayMs(10);RESET_LCD(1);DelayMs(120);/***************page one command**************/SPI_WriteCmd(0xff);SPI_WriteDat(0xff);SPI_WriteDat(0x98);SPI_WriteDat(0x06);SPI_WriteDat(0x04);SPI_WriteDat(0x01);/***************interface mode**************/SPI_WriteCmd(0x08);SPI_WriteDat(0x10);/***************source output direction**************/SPI_WriteCmd(0x22);SPI_WriteDat(0x00);/***************resolution control**************/SPI_WriteCmd(0x30);SPI_WriteDat(0x02);/***************Display Inversion Control**************/SPI_WriteCmd(0x31);SPI_WriteDat(0x02);/***************Power Control**************/SPI_WriteCmd(0x40);SPI_WriteDat(0x15);SPI_WriteCmd(0x41);SPI_WriteDat(0x33);SPI_WriteCmd(0x42);SPI_WriteDat(0x02);SPI_WriteCmd(0x43);SPI_WriteDat(0x09);SPI_WriteCmd(0x44);SPI_WriteDat(0x06);SPI_WriteCmd(0x45);SPI_WriteDat(0xD6);SPI_WriteCmd(0x50);SPI_WriteDat(0x70);SPI_WriteCmd(0x51);SPI_WriteDat(0x70);/***************Vcom Setting**************/SPI_WriteCmd(0x52);SPI_WriteDat(0x00);SPI_WriteCmd(0x53);SPI_WriteDat(0x2B);SPI_WriteCmd(0x54);SPI_WriteDat(0x00);SPI_WriteCmd(0x55);SPI_WriteDat(0x39);/***************Timing**************/SPI_WriteCmd(0x60);SPI_WriteDat(0x07);SPI_WriteCmd(0x61);SPI_WriteDat(0x00);SPI_WriteCmd(0x62);SPI_WriteDat(0x09);SPI_WriteCmd(0x63);SPI_WriteDat(0x00);/***************Power Gamma Settipng**************/SPI_WriteCmd(0xa0);SPI_WriteDat(0x08);SPI_WriteCmd(0xa1);SPI_WriteDat(0x14);SPI_WriteCmd(0xa2);SPI_WriteDat(0x1C) ;SPI_WriteCmd(0xa3);SPI_WriteDat(0x0D);SPI_WriteCmd(0xa4);SPI_WriteDat(0x06) ;SPI_WriteCmd(0xa5);SPI_WriteDat(0x0E);SPI_WriteCmd(0xa6);SPI_WriteDat(0x08);SPI_WriteCmd(0xa7);SPI_WriteDat(0x07);SPI_WriteCmd(0xa8);SPI_WriteDat(0x06);SPI_WriteCmd(0xa9);SPI_WriteDat(0x1A);SPI_WriteCmd(0xaa);SPI_WriteDat(0x0B);SPI_WriteCmd(0xab);SPI_WriteDat(0x04);SPI_WriteCmd(0xac);SPI_WriteDat(0x0a);SPI_WriteCmd(0xad);SPI_WriteDat(0x14);SPI_WriteCmd(0xae);SPI_WriteDat(0x10);SPI_WriteCmd(0xaf);SPI_WriteDat(0x08);/***************Negitive Gamma setting**************/SPI_WriteCmd(0xc0);SPI_WriteDat(0x08);SPI_WriteCmd(0xc1);SPI_WriteDat(0x15);SPI_WriteCmd(0xc2);SPI_WriteDat(0x1d);SPI_WriteCmd(0xc3);SPI_WriteDat(0x0d);SPI_WriteCmd(0xc4);SPI_WriteDat(0x06);SPI_WriteCmd(0xc5);SPI_WriteDat(0x0F);SPI_WriteCmd(0xc6);SPI_WriteDat(0x08);SPI_WriteCmd(0xc7);SPI_WriteDat(0x07);SPI_WriteCmd(0xc8);SPI_WriteDat(0x06);SPI_WriteCmd(0xc9);SPI_WriteDat(0x1a);SPI_WriteCmd(0xca);SPI_WriteDat(0x0b);SPI_WriteCmd(0xcb);SPI_WriteDat(0x04);SPI_WriteCmd(0xcc);SPI_WriteDat(0x0a);SPI_WriteCmd(0xcd);SPI_WriteDat(0x14);SPI_WriteCmd(0xce);SPI_WriteDat(0x10);SPI_WriteCmd(0xcf);SPI_WriteDat(0x08);DelayMs(10);/***************Page 6 Command**************/SPI_WriteCmd(0xff);SPI_WriteDat(0xff);SPI_WriteDat(0x98);SPI_WriteDat(0x06);SPI_WriteDat(0x04);SPI_WriteDat(0x06);/***************GIP Setting**************/SPI_WriteCmd(0x00);SPI_WriteDat(0x21);SPI_WriteCmd(0x01);SPI_WriteDat(0x0A);SPI_WriteCmd(0x02);SPI_WriteDat(0x60);SPI_WriteCmd(0x03);SPI_WriteDat(0x0F);SPI_WriteCmd(0x04);SPI_WriteDat(0x01);SPI_WriteCmd(0x05);SPI_WriteDat(0x01);SPI_WriteCmd(0x06);SPI_WriteDat(0x80);SPI_WriteCmd(0x07);SPI_WriteDat(0x06);SPI_WriteCmd(0x08);SPI_WriteDat(0x01);SPI_WriteCmd(0x09);SPI_WriteDat(0x00);SPI_WriteCmd(0x0A);SPI_WriteDat(0x00);SPI_WriteCmd(0x0B);SPI_WriteDat(0x00);SPI_WriteCmd(0x0C);SPI_WriteDat(0x01);SPI_WriteCmd(0x0D);SPI_WriteDat(0x01);SPI_WriteCmd(0x0E);SPI_WriteDat(0x00);SPI_WriteCmd(0x0F);SPI_WriteDat(0x00);SPI_WriteCmd(0x10);SPI_WriteDat(0xF7);SPI_WriteCmd(0x11);SPI_WriteDat(0xF0);SPI_WriteCmd(0x12);SPI_WriteDat(0x00);SPI_WriteCmd(0x13);SPI_WriteDat(0x00);SPI_WriteCmd(0x14);SPI_WriteDat(0x00);SPI_WriteCmd(0x15);SPI_WriteDat(0xC0);SPI_WriteCmd(0x16);SPI_WriteDat(0x08);SPI_WriteCmd(0x17);SPI_WriteDat(0x01);SPI_WriteCmd(0x18);SPI_WriteDat(0x01);SPI_WriteCmd(0x19);SPI_WriteDat(0x00);SPI_WriteCmd(0x1A);SPI_WriteDat(0x00);SPI_WriteCmd(0x1B);SPI_WriteDat(0x00);SPI_WriteCmd(0x1C);SPI_WriteDat(0x00);SPI_WriteCmd(0x1D);SPI_WriteDat(0x00);SPI_WriteCmd(0x20);SPI_WriteDat(0x01);SPI_WriteCmd(0x21);SPI_WriteDat(0x23);SPI_WriteCmd(0x22);SPI_WriteDat(0x45);SPI_WriteCmd(0x23);SPI_WriteDat(0x67);SPI_WriteCmd(0x24);SPI_WriteDat(0x01);SPI_WriteCmd(0x25);SPI_WriteDat(0x23);SPI_WriteCmd(0x26);SPI_WriteDat(0x45);SPI_WriteCmd(0x27);SPI_WriteDat(0x67);SPI_WriteCmd(0x30);SPI_WriteDat(0x01);SPI_WriteCmd(0x31);SPI_WriteDat(0xDA);SPI_WriteCmd(0x32);SPI_WriteDat(0xCB);SPI_WriteCmd(0x33);SPI_WriteDat(0x22);SPI_WriteCmd(0x34);SPI_WriteDat(0x22);SPI_WriteCmd(0x35);SPI_WriteDat(0x11);SPI_WriteCmd(0x36);SPI_WriteDat(0x00);SPI_WriteCmd(0x37);SPI_WriteDat(0xAD);SPI_WriteCmd(0x38);SPI_WriteDat(0xBC);SPI_WriteCmd(0x39);SPI_WriteDat(0x76);SPI_WriteCmd(0x3A);SPI_WriteDat(0x67);SPI_WriteCmd(0x3B);SPI_WriteDat(0x88);SPI_WriteCmd(0x3C);SPI_WriteDat(0x22);SPI_WriteCmd(0x3D);SPI_WriteDat(0x22);SPI_WriteCmd(0x3E);SPI_WriteDat(0x22);SPI_WriteCmd(0x3F);SPI_WriteDat(0x22);SPI_WriteCmd(0x40);SPI_WriteDat(0x22);/***************page 7 Command**************/SPI_WriteCmd(0xff);SPI_WriteDat(0xff);SPI_WriteDat(0x98);SPI_WriteDat(0x06);SPI_WriteDat(0x04);SPI_WriteDat(0x07);/***************VrEG1/2 Out Enable**************/SPI_WriteCmd(0x18);SPI_WriteDat(0x1D);/***************VGL_REG EN**************/SPI_WriteCmd(0x17);SPI_WriteDat(0x32);/***************Power Bais Control**************/SPI_WriteCmd(0x02);SPI_WriteDat(0x77);SPI_WriteCmd(0xE1);SPI_WriteDat(0x79);SPI_WriteCmd(0x26);SPI_WriteDat(0xB2);/***************Page 0 Command**************/SPI_WriteCmd(0xff);SPI_WriteDat(0xff);SPI_WriteDat(0x98);SPI_WriteDat(0x06);SPI_WriteDat(0x04);SPI_WriteDat(0x00);/***************Interface Pixel Format**************/SPI_WriteCmd(0x3A);SPI_WriteDat(0x70);/***************Display Access Control**************//***************如果出现红蓝反色,请下0x0b,反扫下0x08**************/SPI_WriteCmd(0x36);SPI_WriteDat(0x03);/***************sleep out**************/SPI_WriteCmd(0x11);SPI_WriteDat(0x00);DelayMs(120);/***************diplay on**************/SPI_WriteCmd(0x29);SPI_WriteDat(0x00);DelayMs(20);lcd_read_dat();
}
/*lcd init cmd ---- end*/static int icn6211_gpio_init(struct icn6211 *pdata)
{int ret = 0;/*enable gpio*/if (!gpio_is_valid(pdata->en_gp)) {pr_err("%s,enable gpio [%d] is invalid!\n",__func__, pdata->en_gp);return -1;}ret = gpio_request(pdata->en_gp, "icn6211-en-gpio");if (ret) {pr_err("%s, Unable to request icn6211 en-gpio\n",__func__);}ret = gpio_direction_output(pdata->en_gp, 1);if (ret) {pr_err("%s, Unable to pull up icn6211 en-gpio\n",__func__);}mdelay(5);ret = gpio_direction_output(pdata->en_gp, 0);if (ret) {pr_err("%s, Unable to pull up icn6211 en-gpio\n",__func__);}mdelay(15);ret = gpio_direction_output(pdata->en_gp, 1);if (ret) {pr_err("%s, Unable to pull up icn6211 en-gpio\n",__func__);}/*rgb-lcd-rest gpio*/if (gpio_is_valid(pdata->lcd_rst_gp)) {ret = gpio_request(pdata->lcd_rst_gp, "icn6211-rgb-lcd-rest");if (ret < 0) {pr_err("Failed to request GPIO:%d, ERRNO:%d",pdata->lcd_rst_gp, ret);return -ENODEV;} else {ret = gpio_direction_output(pdata->lcd_rst_gp, 1);if (ret)pr_err("Failed to set icn6211-rgb-lcd-rest\n");mdelay(5);}} else {pr_err("%s, no rgb lcd rest gpio !!!!!\n",__func__);return -1;}/*i2c-scl*/if (gpio_is_valid(pdata->iic_scl_gp)) {ret = gpio_request(pdata->iic_scl_gp, "icn6211-i2c-scl");if (ret < 0) {pr_err("Failed to request GPIO:%d, ERRNO:%d",pdata->iic_scl_gp, ret);return -ENODEV;} else {ret = gpio_direction_output(pdata->iic_scl_gp, 1);if (ret)pr_err("Failed to set icn6211-i2c-scl-gpio\n");mdelay(5);}} else {pr_err("%s, no scl gpio !!!!!\n",__func__);return -1;}/*i2c-sda*/if (gpio_is_valid(pdata->iic_sda_gp)) {ret = gpio_request(pdata->iic_sda_gp, "icn6211-i2c-sda");if (ret < 0) {pr_err("Failed to request GPIO:%d, ERRNO:%d",pdata->iic_sda_gp, ret);return -ENODEV;} else {ret = gpio_direction_output(pdata->iic_sda_gp, 1);if (ret)pr_err("Failed to set icn6211-i2c-sda-gpio\n");mdelay(5);}} else {pr_err("%s, no sda gpio !!!!!\n",__func__);return -1;}/*spi*//*spi-sdi*/if (gpio_is_valid(pdata->spi_sdi_gp)) {ret = gpio_request(pdata->spi_sdi_gp, "icn6211-spi-sdi");if (ret < 0) {pr_err("Failed to request GPIO:%d, ERRNO:%d",pdata->spi_sdi_gp, ret);return -ENODEV;} else {ret = gpio_direction_output(pdata->spi_sdi_gp, 1);if (ret)pr_err("Failed to set icn6211-spi-sdi-gpio\n");mdelay(5);}} else {pr_err("%s, no spi-sdi gpio !!!!!\n",__func__);return -1;}/*spi-sdo*/if (gpio_is_valid(pdata->spi_sdo_gp)) {ret = gpio_request(pdata->spi_sdo_gp, "icn6211-spi-sdo");if (ret < 0) {pr_err("Failed to request GPIO:%d, ERRNO:%d",pdata->spi_sdo_gp, ret);return -ENODEV;} else {ret = gpio_direction_input(pdata->spi_sdo_gp);if (ret)pr_err("Failed to set icn6211-spi-sdo-gpio\n");mdelay(5);}} else {pr_err("%s, no spi-sdo gpio !!!!!\n",__func__);return -1;}/*spi-cs*/if (gpio_is_valid(pdata->spi_csx_gp)) {ret = gpio_request(pdata->spi_csx_gp, "icn6211-spi-cs");if (ret < 0) {pr_err("Failed to request GPIO:%d, ERRNO:%d",pdata->spi_csx_gp, ret);return -ENODEV;} else {ret = gpio_direction_output(pdata->spi_csx_gp, 1);if (ret)pr_err("Failed to set icn6211-spi-cs-gpio\n");mdelay(5);}} else {pr_err("%s, nospi-cs gpio !!!!!\n",__func__);return -1;}/*spi-sc*/if (gpio_is_valid(pdata->spi_sck_gp)) {ret = gpio_request(pdata->spi_sck_gp, "icn6211-spi-sc");if (ret < 0) {pr_err("Failed to request GPIO:%d, ERRNO:%d",pdata->spi_sck_gp, ret);return -ENODEV;} else {ret = gpio_direction_output(pdata->spi_sck_gp, 1);if (ret)pr_err("Failed to set icn6211-spi-sc-gpio\n");mdelay(5);}} else {pr_err("%s, no spi-sc gpio !!!!!\n",__func__);return -1;}return ret;
}static int icn6211_parse_dt(struct device *dev, struct icn6211 *pdata)
{int rc = 0;struct device_node *np = dev->of_node;pdata->en_gp = of_get_named_gpio(np, "icn6211,en-gp", 0);pdata->lcd_rst_gp = of_get_named_gpio(np, "icn6211,lcd-rst-gp", 0);pdata->iic_scl_gp = of_get_named_gpio(np, "icn6211,iic-scl-gp", 0);pdata->iic_sda_gp = of_get_named_gpio(np, "icn6211,iic_sda_gp", 0);pdata->spi_sdi_gp = of_get_named_gpio(np, "icn6211,spi_sdi_gp", 0);pdata->spi_sdo_gp = of_get_named_gpio(np, "icn6211,spi_sdo_gp", 0);pdata->spi_csx_gp = of_get_named_gpio(np, "icn6211,spi_csx_gp", 0);pdata->spi_sck_gp = of_get_named_gpio(np, "icn6211,spi_sck_gp", 0);//pdata->rgb_or_lvds = of_get_property(np, "icn6211,use-rgb", 0);pdata->rgb_or_lvds = 1;//of_property_read_u32(np, "icn6211,slave_addr", &pdata->slave_addr);pdata->slave_addr = 0x2C;pr_info("iic scl=%d,sda=%d\n",pdata->iic_scl_gp, pdata->iic_sda_gp);pr_info("spi sdi=%d,sdo=%d,cs=%d,sc=%d\n",pdata->spi_sdi_gp,pdata->spi_sdo_gp,pdata->spi_csx_gp,pdata->spi_sck_gp);pr_info("icn6211 slave add=0x%X, enable-gpio=%d, lcd-rst=%d\n",pdata->slave_addr,pdata->en_gp,pdata->lcd_rst_gp);return rc;
}static int icn6211_probe(struct platform_device *pdev)
{struct icn6211 *pdata;int ret = 0;pr_info("ICN6211:%s\n",__func__);pdata = kzalloc(sizeof(struct icn6211), GFP_KERNEL);if (!pdata)return -ENOMEM;if (pdev->dev.of_node) {icn6211_parse_dt(&pdev->dev, pdata);} else {pr_err("ICN6211: no device node,exit...\n");ret = -1;goto err_exit;}ret = icn6211_gpio_init(pdata);if (ret) {pr_err("%s: Failed to configure GPIOs\n", __func__);goto err_exit;}mutex_init(&pdata->icn6211_mutex);dev_set_drvdata(&pdev->dev, pdata);icn6211_pdata = pdata;lcd_init();mdelay(5);icn6211_init(pdata);mdelay(5);icn6211_dump(pdata);return 0;err_exit:kfree(pdata);icn6211_pdata = NULL;return ret;
}static const struct of_device_id icn6211_of_match[] = {{ .compatible = "qcom,icn6211",},{},
};static int icn6211_resume(struct device *pdev)
{/*  Reset_chip();mdss_mipi_i2c_init(); */return 0;
}static int icn6211_remove(struct platform_device *pdev) {return 0;
}static int icn6211_suspend(struct device *tdev) {/* gpio_direction_output(lt8912b_pdata->rst_gpio, 0); */return 0;
}static const struct dev_pm_ops icn6211_pm_ops =
{.suspend = icn6211_suspend,.resume = icn6211_resume,
};static struct platform_driver icn6211_driver = {.driver = {.name = "qcom,icn6211",.owner    = THIS_MODULE,.of_match_table = icn6211_of_match,.pm = &icn6211_pm_ops,},.probe    = icn6211_probe,.remove   = icn6211_remove,
};static int __init icn6211_rgb_lvds_init(void)
{int ret;ret = platform_driver_register(&icn6211_driver);if (ret)printk(KERN_ERR "icn6211_driver: probe failed: %d\n", ret);return ret;
}static void __exit icn6211_rgb_lvds_exit(void)
{platform_driver_unregister(&icn6211_driver);
}subsys_initcall(icn6211_rgb_lvds_init);
//module_init(mipi_gpio_i2c_init);
//late_initcall(mipi_gpio_i2c_init);
module_exit(icn6211_rgb_lvds_exit);
MODULE_LICENSE("GPL");

另外一个版本,i2c 使用的是硬件的,非模拟i2c。前面一个版本是 i2c和SPI都模拟了

/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 and* only version 2 as published by the Free Software Foundation.** This program is distributed in the hope that it will be useful,* 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.** * version:1.0* data:2017.9.9* function description : mipi-2-rgb (icn6211) device driver which tranfer msg via i2c**/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
//#include "msm_dba_internal.h"
#include <linux/mdss_io_util.h>
#include <linux/slab.h>/********************************** simulated spi & initialize rgb lcd via spi  begein ***********************************************/
/* GPIO126 / GPIO60 / GPIO38 / GPIO31 / GPIO32 */
#define DISP_CSX    (126) /* cs */
#define DISP_WRX    (38)  /* scl */
#define DISP_SDO    (31)  /* sdo */
#define DISP_SDI    (32)  /* sdi */
#define DISP_RST    (60)  /* rst */#define LCD_W  800
#define LCD_H  480/**************************************************************otm8019 lcd  -->zzd***************************************************************/
#define SET_SPI_CS_HIGH()   gpio_direction_output(DISP_CSX, 1)//CS
#define SET_SPI_CS_LOW()    gpio_direction_output(DISP_CSX, 0)//CS#define SET_SPI_CLK_HIGH()    gpio_direction_output(DISP_WRX, 1)//CLK
#define SET_SPI_CLK_LOW()   gpio_direction_output(DISP_WRX, 0)//CLK#define SET_SPI_MOSI_HIGH() gpio_direction_output(DISP_SDI, 1)//MOSI
#define SET_SPI_MOSI_LOW()  gpio_direction_output(DISP_SDI, 0)//MOSI#define SET_SPI_MISO()      gpio_direction_input(DISP_SDO)//MISO#define RESET_SCREEN()      { gpio_direction_output(DISP_RST, 1);gpio_direction_output(DISP_RST, 0);udelay(100);gpio_direction_output(DISP_RST, 1);udelay(100);}#define OTM8018B_WCMDH  0x20
#define OTM8018B_WCMDL  0x00
#define OTM8018B_WDATA  0x40
#define LCD_DELAY_1MS    15000          // Sufficient under 1Ghz
#define SPI_DELAY        200
#define ICN6211_SLAVE_ADD   0x2Cvoid lcd_gpio_init(void)
{int ret = 0;pr_info("[spilcd] %s, begin...\n",__func__);ret = gpio_request(DISP_RST, "display-spi-rst");if (ret) {pr_err("DISP_RST gpio request failed111\n");return;}gpio_direction_output(DISP_RST, 1);ret = gpio_request(DISP_WRX, "display-spi-clk");if (ret) {pr_err("DISP_WRX gpio request failed111\n");return;}SET_SPI_CLK_HIGH();ret = gpio_request(DISP_SDO, "display-spi-sdo");if (ret) {pr_err("DISP_SDO gpio request failed111\n");return;}SET_SPI_MOSI_HIGH();ret = gpio_request(DISP_CSX, "display-spi-cs");if (ret) { pr_err("DISP_CSX gpio request failed111\n");return;}SET_SPI_CS_HIGH();ret = gpio_request(DISP_SDI, "display-spi-sdi");if (ret) {pr_err("DISP_SDI gpio request failed111\n");return;}SET_SPI_MISO();pr_info("[spilcd] %s, end...\n",__func__);return ;
}static void delay_loop(int delay)
{volatile int j,i;for(j = 0; j < delay; j++)i++;
}void Spi_Write_Byte( unsigned char ddat )
{unsigned char i;for (i = 0; i< 8; i++){//SCL0=0;//IM3=0//delay(10);SET_SPI_CLK_LOW();if (ddat&0x80) {SET_SPI_MOSI_HIGH();} else {SET_SPI_MOSI_LOW();}//SET_SPI_CLK_LOW();delay_loop(SPI_DELAY);SET_SPI_CLK_HIGH();delay_loop(SPI_DELAY);//SCL0=0;//IM3=0//SCL0=1;//delay(10);//ddat=(ddat<<=1);ddat <<= 1;}return ;
}void SPI_Write_CMD_OTM8018B(unsigned short SPI_data)//word
{SET_SPI_CS_LOW();Spi_Write_Byte(OTM8018B_WCMDH);Spi_Write_Byte((SPI_data&0xFF00) >> 8);//CSB=1;//SET_SPI_CS_LOW();Spi_Write_Byte(OTM8018B_WCMDL);Spi_Write_Byte(SPI_data & 0x00FF);SET_SPI_CS_HIGH();
}void SPI_Write_DATA_OTM8018B(unsigned char  SPI_data)
{SET_SPI_CS_LOW();Spi_Write_Byte(OTM8018B_WDATA);Spi_Write_Byte(SPI_data);SET_SPI_CS_HIGH();
}void otm8019_ldi_init(void)
{   SET_SPI_CLK_LOW();SPI_Write_CMD_OTM8018B(0xFF00); SPI_Write_DATA_OTM8018B(0x80); SPI_Write_CMD_OTM8018B(0xFF01); SPI_Write_DATA_OTM8018B(0x19); SPI_Write_CMD_OTM8018B(0xFF02); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xFF80); SPI_Write_DATA_OTM8018B(0x80); SPI_Write_CMD_OTM8018B(0xFF81); SPI_Write_DATA_OTM8018B(0x19); SPI_Write_CMD_OTM8018B(0xC48A); SPI_Write_DATA_OTM8018B(0x40); SPI_Write_CMD_OTM8018B(0xB3A6); SPI_Write_DATA_OTM8018B(0x20);      //SPI_Write_CMD_OTM8018B(0xB3A7); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xC090); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC091); SPI_Write_DATA_OTM8018B(0x15); SPI_Write_CMD_OTM8018B(0xC092); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC093); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC094); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC095); SPI_Write_DATA_OTM8018B(0x03); SPI_Write_CMD_OTM8018B(0xC0B4); SPI_Write_DATA_OTM8018B(0x70); SPI_Write_CMD_OTM8018B(0xC181); SPI_Write_DATA_OTM8018B(0x33); SPI_Write_CMD_OTM8018B(0xC481); SPI_Write_DATA_OTM8018B(0x81); SPI_Write_CMD_OTM8018B(0xC487); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC489); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC582); SPI_Write_DATA_OTM8018B(0xB0); SPI_Write_CMD_OTM8018B(0xC590); SPI_Write_DATA_OTM8018B(0x4E); SPI_Write_CMD_OTM8018B(0xC591); SPI_Write_DATA_OTM8018B(0x34); SPI_Write_CMD_OTM8018B(0xC592); SPI_Write_DATA_OTM8018B(0x06); SPI_Write_CMD_OTM8018B(0xC593); SPI_Write_DATA_OTM8018B(0x91); SPI_Write_CMD_OTM8018B(0xC594); SPI_Write_DATA_OTM8018B(0x33); SPI_Write_CMD_OTM8018B(0xC595); SPI_Write_DATA_OTM8018B(0x34); SPI_Write_CMD_OTM8018B(0xC596); SPI_Write_DATA_OTM8018B(0x23); SPI_Write_CMD_OTM8018B(0xC5B1); SPI_Write_DATA_OTM8018B(0xA8); SPI_Write_CMD_OTM8018B(0xD800); SPI_Write_DATA_OTM8018B(0x6F); SPI_Write_CMD_OTM8018B(0xD801); SPI_Write_DATA_OTM8018B(0x6F); SPI_Write_CMD_OTM8018B(0xD900); SPI_Write_DATA_OTM8018B(0x23);SPI_Write_CMD_OTM8018B(0xCE80); SPI_Write_DATA_OTM8018B(0x86); SPI_Write_CMD_OTM8018B(0xCE81); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCE82); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCE83); SPI_Write_DATA_OTM8018B(0x85); SPI_Write_CMD_OTM8018B(0xCE84); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCE85); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCE86); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCE87); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCE88); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCE89); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCE8A); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCE8B); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEA0); SPI_Write_DATA_OTM8018B(0x18); SPI_Write_CMD_OTM8018B(0xCEA1); SPI_Write_DATA_OTM8018B(0x05); SPI_Write_CMD_OTM8018B(0xCEA2); SPI_Write_DATA_OTM8018B(0x83); SPI_Write_CMD_OTM8018B(0xCEA3); SPI_Write_DATA_OTM8018B(0x39); SPI_Write_CMD_OTM8018B(0xCEA4); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEA5); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEA6); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEA7); SPI_Write_DATA_OTM8018B(0x18); SPI_Write_CMD_OTM8018B(0xCEA8); SPI_Write_DATA_OTM8018B(0x04); SPI_Write_CMD_OTM8018B(0xCEA9); SPI_Write_DATA_OTM8018B(0x83); SPI_Write_CMD_OTM8018B(0xCEAA); SPI_Write_DATA_OTM8018B(0x3A); SPI_Write_CMD_OTM8018B(0xCEAB); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEAC); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEAD); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEB0); SPI_Write_DATA_OTM8018B(0x18); SPI_Write_CMD_OTM8018B(0xCEB1); SPI_Write_DATA_OTM8018B(0x03); SPI_Write_CMD_OTM8018B(0xCEB2); SPI_Write_DATA_OTM8018B(0x83); SPI_Write_CMD_OTM8018B(0xCEB3); SPI_Write_DATA_OTM8018B(0x3B); SPI_Write_CMD_OTM8018B(0xCEB4); SPI_Write_DATA_OTM8018B(0x86); SPI_Write_CMD_OTM8018B(0xCEB5); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEB6); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEB7); SPI_Write_DATA_OTM8018B(0x18); SPI_Write_CMD_OTM8018B(0xCEB8); SPI_Write_DATA_OTM8018B(0x02); SPI_Write_CMD_OTM8018B(0xCEB9); SPI_Write_DATA_OTM8018B(0x83); SPI_Write_CMD_OTM8018B(0xCEBA); SPI_Write_DATA_OTM8018B(0x3C); SPI_Write_CMD_OTM8018B(0xCEBB); SPI_Write_DATA_OTM8018B(0x88); SPI_Write_CMD_OTM8018B(0xCEBC); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCEBD); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCFC0); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCFC1); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCFC2); SPI_Write_DATA_OTM8018B(0x20); SPI_Write_CMD_OTM8018B(0xCFC3); SPI_Write_DATA_OTM8018B(0x20); SPI_Write_CMD_OTM8018B(0xCFC4); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCFC5); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCFC6); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCFC7); SPI_Write_DATA_OTM8018B(0x02); SPI_Write_CMD_OTM8018B(0xCFC8); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCFC9); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCFD0); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBC0); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBC1); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBC2); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBC3); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBC4); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBC5); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBC6); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBC7); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBC8); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBC9); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBCA); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBCB); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBCC); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBCD); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBCE); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBD0); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBD5); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBD6); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBD7); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBD8); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBD9); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBDA); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBDB); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBDC); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBDD); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBDE); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCBE0); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBE1); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBE2); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBE3); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBE4); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCBE5); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC80); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC81); SPI_Write_DATA_OTM8018B(0x26); SPI_Write_CMD_OTM8018B(0xCC82); SPI_Write_DATA_OTM8018B(0x09); SPI_Write_CMD_OTM8018B(0xCC83); SPI_Write_DATA_OTM8018B(0x0B); SPI_Write_CMD_OTM8018B(0xCC84); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCC85); SPI_Write_DATA_OTM8018B(0x25); SPI_Write_CMD_OTM8018B(0xCC86); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC87); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC88); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC89); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC90); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC91); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC92); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC93); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC94); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC95); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC9A); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC9B); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC9C); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC9D); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCC9E); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCA0); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCA1); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCA2); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCA3); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCA4); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCA5); SPI_Write_DATA_OTM8018B(0x25); SPI_Write_CMD_OTM8018B(0xCCA6); SPI_Write_DATA_OTM8018B(0x02); SPI_Write_CMD_OTM8018B(0xCCA7); SPI_Write_DATA_OTM8018B(0x0C); SPI_Write_CMD_OTM8018B(0xCCA8); SPI_Write_DATA_OTM8018B(0x0A); SPI_Write_CMD_OTM8018B(0xCCA9); SPI_Write_DATA_OTM8018B(0x26); SPI_Write_CMD_OTM8018B(0xCCAA); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCB0); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCB1); SPI_Write_DATA_OTM8018B(0x25); SPI_Write_CMD_OTM8018B(0xCCB2); SPI_Write_DATA_OTM8018B(0x0C); SPI_Write_CMD_OTM8018B(0xCCB3); SPI_Write_DATA_OTM8018B(0x0A); SPI_Write_CMD_OTM8018B(0xCCB4); SPI_Write_DATA_OTM8018B(0x02); SPI_Write_CMD_OTM8018B(0xCCB5); SPI_Write_DATA_OTM8018B(0x26); SPI_Write_CMD_OTM8018B(0xCCB6); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCB7); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCB8); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCB9); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCC0); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCC1); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCC2); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCC3); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCC4); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCC5); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCCA); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCCB); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCCC); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCCD); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCCE); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCD0); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCD1); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCD2); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCD3); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCD4); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xCCD5); SPI_Write_DATA_OTM8018B(0x26); SPI_Write_CMD_OTM8018B(0xCCD6); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xCCD7); SPI_Write_DATA_OTM8018B(0x09); SPI_Write_CMD_OTM8018B(0xCCD8); SPI_Write_DATA_OTM8018B(0x0B); SPI_Write_CMD_OTM8018B(0xCCD9); SPI_Write_DATA_OTM8018B(0x25); SPI_Write_CMD_OTM8018B(0xCCDA); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xE100); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xE101); SPI_Write_DATA_OTM8018B(0x07); SPI_Write_CMD_OTM8018B(0xE102); SPI_Write_DATA_OTM8018B(0x10); SPI_Write_CMD_OTM8018B(0xE103); SPI_Write_DATA_OTM8018B(0x22); SPI_Write_CMD_OTM8018B(0xE104); SPI_Write_DATA_OTM8018B(0x40); SPI_Write_CMD_OTM8018B(0xE105); SPI_Write_DATA_OTM8018B(0x56); SPI_Write_CMD_OTM8018B(0xE106); SPI_Write_DATA_OTM8018B(0x66); SPI_Write_CMD_OTM8018B(0xE107); SPI_Write_DATA_OTM8018B(0x99); SPI_Write_CMD_OTM8018B(0xE108); SPI_Write_DATA_OTM8018B(0x88); SPI_Write_CMD_OTM8018B(0xE109); SPI_Write_DATA_OTM8018B(0x9F); SPI_Write_CMD_OTM8018B(0xE10A); SPI_Write_DATA_OTM8018B(0x6A); SPI_Write_CMD_OTM8018B(0xE10B); SPI_Write_DATA_OTM8018B(0x5A); SPI_Write_CMD_OTM8018B(0xE10C); SPI_Write_DATA_OTM8018B(0x74); SPI_Write_CMD_OTM8018B(0xE10D); SPI_Write_DATA_OTM8018B(0x61); SPI_Write_CMD_OTM8018B(0xE10E); SPI_Write_DATA_OTM8018B(0x68); SPI_Write_CMD_OTM8018B(0xE10F); SPI_Write_DATA_OTM8018B(0x61); SPI_Write_CMD_OTM8018B(0xE110); SPI_Write_DATA_OTM8018B(0x5B); SPI_Write_CMD_OTM8018B(0xE111); SPI_Write_DATA_OTM8018B(0x4E); SPI_Write_CMD_OTM8018B(0xE112); SPI_Write_DATA_OTM8018B(0x44); SPI_Write_CMD_OTM8018B(0xE113); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xE200); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xE201); SPI_Write_DATA_OTM8018B(0x07); SPI_Write_CMD_OTM8018B(0xE202); SPI_Write_DATA_OTM8018B(0x10); SPI_Write_CMD_OTM8018B(0xE203); SPI_Write_DATA_OTM8018B(0x22); SPI_Write_CMD_OTM8018B(0xE204); SPI_Write_DATA_OTM8018B(0x40); SPI_Write_CMD_OTM8018B(0xE205); SPI_Write_DATA_OTM8018B(0x56); SPI_Write_CMD_OTM8018B(0xE206); SPI_Write_DATA_OTM8018B(0x66); SPI_Write_CMD_OTM8018B(0xE207); SPI_Write_DATA_OTM8018B(0x99); SPI_Write_CMD_OTM8018B(0xE208); SPI_Write_DATA_OTM8018B(0x88); SPI_Write_CMD_OTM8018B(0xE209); SPI_Write_DATA_OTM8018B(0x9F); SPI_Write_CMD_OTM8018B(0xE20A); SPI_Write_DATA_OTM8018B(0x6A); SPI_Write_CMD_OTM8018B(0xE20B); SPI_Write_DATA_OTM8018B(0x5A); SPI_Write_CMD_OTM8018B(0xE20C); SPI_Write_DATA_OTM8018B(0x74); SPI_Write_CMD_OTM8018B(0xE20D); SPI_Write_DATA_OTM8018B(0x61); SPI_Write_CMD_OTM8018B(0xE20E); SPI_Write_DATA_OTM8018B(0x68); SPI_Write_CMD_OTM8018B(0xE20F); SPI_Write_DATA_OTM8018B(0x61); SPI_Write_CMD_OTM8018B(0xE210); SPI_Write_DATA_OTM8018B(0x5B); SPI_Write_CMD_OTM8018B(0xE211); SPI_Write_DATA_OTM8018B(0x4E); SPI_Write_CMD_OTM8018B(0xE212); SPI_Write_DATA_OTM8018B(0x44); SPI_Write_CMD_OTM8018B(0xE213); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC480); SPI_Write_DATA_OTM8018B(0x30); SPI_Write_CMD_OTM8018B(0xC098); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC0A9); SPI_Write_DATA_OTM8018B(0x0A); SPI_Write_CMD_OTM8018B(0xC1B0); SPI_Write_DATA_OTM8018B(0x20); SPI_Write_CMD_OTM8018B(0xC1B1); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC1B2); SPI_Write_DATA_OTM8018B(0x00); SPI_Write_CMD_OTM8018B(0xC0E1); SPI_Write_DATA_OTM8018B(0x40); SPI_Write_CMD_OTM8018B(0xC0E2); SPI_Write_DATA_OTM8018B(0x30); SPI_Write_CMD_OTM8018B(0xC180); SPI_Write_DATA_OTM8018B(0x03); SPI_Write_CMD_OTM8018B(0xC181); SPI_Write_DATA_OTM8018B(0x33); SPI_Write_CMD_OTM8018B(0xC1A0); SPI_Write_DATA_OTM8018B(0xE8); SPI_Write_CMD_OTM8018B(0xB690); SPI_Write_DATA_OTM8018B(0xB4); //delay_loop_1ms(10); mdelay(10);SPI_Write_CMD_OTM8018B(0xFB00); SPI_Write_DATA_OTM8018B(0x01); SPI_Write_CMD_OTM8018B(0xFF00); SPI_Write_DATA_OTM8018B(0xFF); SPI_Write_CMD_OTM8018B(0xFF01); SPI_Write_DATA_OTM8018B(0xFF); SPI_Write_CMD_OTM8018B(0xFF02); SPI_Write_DATA_OTM8018B(0xFF); SPI_Write_CMD_OTM8018B(0x3600); SPI_Write_DATA_OTM8018B(0xc0); SPI_Write_CMD_OTM8018B(0x3A00); SPI_Write_DATA_OTM8018B(0x70); SPI_Write_CMD_OTM8018B(0x1100); SPI_Write_DATA_OTM8018B(0x00); //delay_loop_1ms(120); mdelay(120);SPI_Write_CMD_OTM8018B(0x2900); SPI_Write_DATA_OTM8018B(0x00);
}void lcd_otm8019_init(void)
{pr_info("[spilcd] %s,starting...\n",__func__);lcd_gpio_init();/* LCD reset*/RESET_SCREEN();/*LCD driver init*/otm8019_ldi_init();pr_info("[spilcd] %s,end...\n",__func__);
}
/********************************** simulated spi & initialize rgb lcd via spi  end ***********************************************/struct icn6211 {int enable_gpio;struct i2c_client *client;struct regulator *vdd1;struct regulator *vdd2;struct regulator *vdd3;struct regulator *vcc_i2c;struct mutex icn6211_mutex;
};struct icn6211_cmd {char reg_add;char reg_val;
};static const struct icn6211_cmd cmd_table[] = {#if 0{0x20, 0xE0},{0x21, 0x20},{0x22, 0x31},{0x23, 0xA0},{0x24, 0x30},{0x25, 0x28},{0x26, 0x00},{0x27, 0x0D},{0x28, 0x03},{0x29, 0x1D},{0x34, 0x80},{0x36, 0xA0},{0xB5, 0xA0},{0x5C, 0xFF},{0x2A, 0x01},{0x56, 0x90},{0x6B, 0x71},{0x69, 0x2E},{0x10, 0x40},{0x11, 0x88},{0xB6, 0x20},{0x51, 0x20},//{0x14, 0x43},//{0x2a, 0x49},{0x09, 0x10}
#endif{0x20, 0xE0},{0x21, 0x20},{0x22, 0x31},{0x23, 0x30},{0x24, 0x04},{0x25, 0x2C},{0x26, 0x00},{0x27, 0x0F},{0x28, 0x01},{0x29, 0x10},{0x34, 0x80},{0x36, 0x30},{0xB5, 0xA0},{0x5C, 0xFF},{0x2A, 0x01},{0x56, 0x90},{0x6B, 0x71},{0x69, 0x21},{0x10, 0x45},{0x11, 0x88},{0xB6, 0x20},{0x51, 0x20},/*register 0x14 & 0x2a are test mode register*///{0x14, 0x43},//{0x2a, 0x49},{0x09, 0x10}
};#define ICN6211_CMD_CNT (sizeof(cmd_table)/sizeof(cmd_table[0]))static int icn6211_i2c_write(struct icn6211 *pdata)
{int rc = 0;int i = 0;const struct icn6211_cmd *cmd_list = cmd_table;mutex_lock(&pdata->icn6211_mutex);if (pdata->client) {for (i = 0; i < ICN6211_CMD_CNT; i++){pr_info("ICN6211 write: reg_add=0x%X, reg_val=0x%X\n", (cmd_list+i)->reg_add, (cmd_list+i)->reg_val);rc = i2c_smbus_write_byte_data(pdata->client, (cmd_list+i)->reg_add, (cmd_list+i)->reg_val);if (rc < 0) {mutex_unlock(&pdata->icn6211_mutex);return rc;}}}mutex_unlock(&pdata->icn6211_mutex);return rc;
}static int icn6211_i2c_read(struct icn6211 *pdata)
{int rc = 0;int i = 0;const struct icn6211_cmd *cmd_list = cmd_table;mutex_lock(&pdata->icn6211_mutex);if (pdata->client) {for (i = 0; i < ICN6211_CMD_CNT; i++){rc = i2c_smbus_read_byte_data(pdata->client, (cmd_list+i)->reg_add);if (rc < 0) {mutex_unlock(&pdata->icn6211_mutex);return rc;}pr_info("ICN6211 read : reg_add=0x%X, reg_val=0x%X\n", (cmd_list+i)->reg_add, rc);}rc = i2c_smbus_read_byte_data(pdata->client, 0x00);pr_info("ICN6211 read : reg_add=0x00, reg_val=0x%X\n", rc);}mutex_unlock(&pdata->icn6211_mutex);return rc;
}static void icn6211_mipi_test(struct icn6211 *pdata)
{int rc = 0;mutex_lock(&pdata->icn6211_mutex);rc = i2c_smbus_write_byte_data(pdata->client, 0x88, 0x80);if (rc < 0) {pr_err("%s, i2c_smbus_write_byte_data error!\n",__func__);mutex_unlock(&pdata->icn6211_mutex);return ;}pr_info("%s, rc=%d\n", __func__,rc);rc = 5;rc = i2c_smbus_read_byte_data(pdata->client, 0x80);pr_info("ICN6211 read : reg_add=0x80, reg_val=0x%X\n", rc);rc = i2c_smbus_read_byte_data(pdata->client, 0x81);pr_info("ICN6211 read : reg_add=0x81, reg_val=0x%X\n", rc);mutex_unlock(&pdata->icn6211_mutex);return ;}static int icn6211_power_on(struct icn6211 *pdata, int on)
{int ret = 0;if (on) {if (!IS_ERR(pdata->vdd1)) {ret = regulator_enable(pdata->vdd1);if (ret) {dev_err(&pdata->client->dev,"Regulator vdd1 enable failed ret=%d\n", ret);goto err_enable_vdd1;}}if (!IS_ERR(pdata->vdd2)) {ret = regulator_enable(pdata->vdd2);if (ret) {dev_err(&pdata->client->dev,"Regulator vdd2 enable failed ret=%d\n", ret);goto err_enable_vdd2;}}if (!IS_ERR(pdata->vdd3)) {ret = regulator_enable(pdata->vdd3);if (ret) {dev_err(&pdata->client->dev,"Regulator vdd3 enable failed ret=%d\n", ret);goto err_enable_vdd3;}}} else {if (!IS_ERR(pdata->vdd1))ret = regulator_disable(pdata->vdd1);if (!IS_ERR(pdata->vdd2))ret = regulator_disable(pdata->vdd2);if (!IS_ERR(pdata->vdd3))ret = regulator_disable(pdata->vdd3);}return ret;err_enable_vdd3:if (!IS_ERR(pdata->vdd2))regulator_disable(pdata->vdd2);
err_enable_vdd2:if (!IS_ERR(pdata->vdd1))regulator_disable(pdata->vdd1);
err_enable_vdd1:return ret;}static int icn6211_power_init(struct icn6211 *pdata)
{int ret = 0;pdata->vdd1 = regulator_get(&pdata->client->dev, "vdd1");if (IS_ERR(pdata->vdd1)) {ret = PTR_ERR(pdata->vdd1);dev_info(&pdata->client->dev,"Regulator get failed avdd ret=%d\n", ret);}pdata->vdd2 = regulator_get(&pdata->client->dev, "vdd2");if (IS_ERR(pdata->vdd2)) {ret = PTR_ERR(pdata->vdd2);dev_info(&pdata->client->dev,"Regulator get failed avdd ret=%d\n", ret);}pdata->vdd3 = regulator_get(&pdata->client->dev, "vdd3");if (IS_ERR(pdata->vdd3)) {ret = PTR_ERR(pdata->vdd3);dev_info(&pdata->client->dev,"Regulator get failed avdd ret=%d\n", ret);}return ret;
}static int icn6211_gpio_init(struct icn6211 *pdata)
{int ret = 0;pr_info("%s, icn6211-engpio is %d\n",__func__,pdata->enable_gpio);if (!gpio_is_valid(pdata->enable_gpio)) {pr_err("%s,enable gpio [%d] is invalid!\n",__func__, pdata->enable_gpio);return -1;}ret = gpio_request(pdata->enable_gpio, "icn6211-en-gpio");if (ret) {pr_err("%s, Unable to request icn6211 en-gpio\n",__func__);}ret = gpio_direction_output(pdata->enable_gpio, 1);if (ret) {pr_err("%s, Unable to pull up icn6211 en-gpio\n",__func__);}mdelay(5);ret = gpio_direction_output(pdata->enable_gpio, 0);if (ret) {pr_err("%s, Unable to pull up icn6211 en-gpio\n",__func__);}mdelay(15);ret = gpio_direction_output(pdata->enable_gpio, 1);if (ret) {pr_err("%s, Unable to pull up icn6211 en-gpio\n",__func__);}return ret;
}static int icn6211_parse_dt(struct device *dev, struct icn6211 *pdata)
{int rc = 0;struct device_node *np = dev->of_node;pdata->enable_gpio = of_get_named_gpio(np, "icn6211-en-gp", 0);return rc;
}static int icn6211_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct icn6211 *pdata;int ret = 0;pr_err("ICN6211:%s\n",__func__);if (!client || !client->dev.of_node) {dev_err(&client->dev, "%s: invalid input\n\n",__func__);return -EINVAL;}if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {dev_err(&client->dev, "icn6211  I2C not supported\n");return -ENODEV;}pdata = devm_kzalloc(&client->dev,sizeof(struct icn6211), GFP_KERNEL);if (!pdata)return -ENOMEM;ret = icn6211_parse_dt(&client->dev, pdata);if (ret) {pr_err("%s: Failed to parse DT\n", __func__);goto err_dt_parse;}pdata->client = client;ret = icn6211_gpio_init(pdata);if (ret) {pr_err("%s: Failed to configure GPIOs\n", __func__);goto err_gpio_cfg;}if (0)ret = icn6211_power_init(pdata);if (0) {ret = icn6211_power_on(pdata, 1);if (ret) {pr_err("%s, power on faild !\n",__func__);goto err_power_on;}}mutex_init(&pdata->icn6211_mutex);dev_set_drvdata(&client->dev, pdata);mutex_lock(&pdata->icn6211_mutex);lcd_otm8019_init();mutex_unlock(&pdata->icn6211_mutex);mdelay(5);icn6211_i2c_write(pdata);mdelay(5);icn6211_i2c_read(pdata);msleep(2000);icn6211_mipi_test(pdata);return 0;
err_power_on:
err_gpio_cfg:
err_dt_parse:devm_kfree(&client->dev, pdata);return ret;
}static int icn6211_resume(struct device *tdev)
{return 0;
}static int icn6211_suspend(struct device *tdev)
{return 0;
}
static int icn6211_remove(struct i2c_client *client)
{return 0;
}static const struct of_device_id icn6211_mipi_rgb_of_match[] = {{ .compatible = "qcom,icn6211_mipi_rgb",},{},
};static const struct i2c_device_id icn6211_id[] = {{"icn6211_mipi_rgb", 0},{},
};static const struct dev_pm_ops icn6211_pm_ops = { .suspend = icn6211_suspend,.resume = icn6211_resume,
};static struct i2c_driver icn6211_driver = {.driver = {.name = "qcom,icn6211_mipi_rgb",.owner    = THIS_MODULE,.of_match_table = icn6211_mipi_rgb_of_match,.pm = &icn6211_pm_ops,},.probe    = icn6211_probe,.remove   = icn6211_remove,.id_table = icn6211_id,
};module_i2c_driver(icn6211_driver);
MODULE_DESCRIPTION("ICN6211 MIPI-RGB driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("i2c:icn6211_mipi_rgb");

Qualcomm MSM8937 ICN6211 MIPI-2-RGB 芯片驱动相关推荐

  1. 联芯 1860平台 icn6211 mipi to RGB 转换芯片 调试 和 st7789 LCD调试spi 9bit 模式

    关键字:联芯科技,LC1860,LC186x,Chipone Technology,icn6211,mipi bridge,mipi to RGB,mipi转换芯片,RGB666,st7789,st7 ...

  2. MIPI转换芯片、ICN6211、ICN6202、MIPI转RGB、MiPI转LVDS、分辨率最高1080P、MIPI转双路LVDS

    MIPI转换芯片.ICN6211.ICN6202.MIPI转RGB.MiPI转LVDS.分辨率最高1080P.MIPI转双路LVDS 1:ICN6211是一颗MIPI转RGB的桥接芯片如下图 2:IC ...

  3. 基于全志T133-s3(Tina Linux)移植5寸RGB显示屏驱动

    基于全志T133-s3(Tina Linux)移植5寸RGB显示屏驱动 1.硬件电路 2.LCD实物图 3.LCD 的驱动 4.uboot配置 4.1.配置文件 4.2.uboot设备树 5.kern ...

  4. MIPI换EDP芯片-LT8911EXB芯片,商显行业新选择

    LT8911EXB:MIPI TO EDP芯片.其主要功能图如下所示: 产品特征: Support Single Port MIPI CSI/DSI Input Compliant with D-PH ...

  5. 基于STM32的DS1302时钟芯片驱动

    基于STM32的DS1302时钟芯片驱动 /****************************************************************************** ...

  6. 多通道_人机交互界面的多通道RGB LED驱动设计

    现在的产品变得非常智能且彼此相互连接.扬声器.电视.冰箱.机顶盒和烟雾探测器等器件不再只是处在某一位置的工具 - 用户可远程或通过语音唤醒控制它们.这些器件比以前更加智能,这意味着它们还需要更加智慧的 ...

  7. 蓝桥杯单片机DS1302时钟芯片驱动代码注释

    蓝桥杯单片机DS1302时钟芯片驱动代码之前的疑惑注释了下 /* DS1302 芯片包含一个 实时时钟/日历和 31 字节的静态 RAM. 与时钟/RAM 通讯只需要三根线: CE,I/O (数据线) ...

  8. TMI8150芯片驱动开发

    TMI8150芯片驱动开发 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TMI8150芯片驱动开发 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 T ...

  9. PCF8563 时钟芯片驱动代码

    //C文件 /********************************************************************************************* ...

最新文章

  1. 解决Mac上VSCdoe断点失效问题
  2. python实现阿里云域名绑定动态IP
  3. 【译】Federated Learning: Bringing Machine Learning to the edge with Kotlin and Android
  4. 你应该如何选择笔记软件?
  5. mysql主从配置常见问题_mysql 主从复制配置,以及常见问题解决!
  6. linux 退后根目录,linux下半部与退后执行的工作
  7. 互联网日报 | 小米11取消随机附送充电器;苏宁30周年发庆生红包;2021年全国两会召开时间确定...
  8. java 线程参数 用final,JAVA 关于final修饰变量参数
  9. Motion and Optical Flow
  10. 洗车房,无人车的噩梦
  11. LuoguP2756 飞行员配对方案问题(最大流)
  12. 测试工具JMeter详细安装配置教程(保证一次安装成功)
  13. linux下 Wowza安装与ffmpeg测试
  14. 不同光栅的结构特点、优缺点以及光栅的选择
  15. C中 stdarg.h
  16. 不懂怎么搞定人的进来:年业绩千万的老销售给你几招实惠的-没有干货立即跳楼
  17. Kubernetes如何被应用在华为
  18. 数论 判断素数:普通素数判别 线性筛 二次筛法求素数 米勒拉宾素数检验
  19. 2019多校第一场 HDU6578 - Blank(DP,思维,滚动数组优化空间)
  20. 【C语言学习】输入输出

热门文章

  1. 电商平台接口:实现高效对接,助力商家发展
  2. vc 6 中使用 attach to process
  3. javaweb后台开发框架
  4. QUIC 协议初探 - iOS 实践
  5. EXCEL中数据透视表的(空白)如何不显示,并且不影响数据更新
  6. Off-policy Actor-critic in RL
  7. 小林和单字母.CN域名的那些事(上)
  8. 写文章一年了,我用到的工具都在这儿了
  9. 正大国际期货:外盘期货如何开设账户?
  10. a 标签之假链接 和假链接