Skip to content

Commit 4532bf9

Browse files
committed
MINIARM: drm/rockchip: mipi: dsi: add tc358762 support
Change-Id: I4a2db55f41e6d9f53fb16d7ce240358e4a7636fd Signed-off-by: Xubilv <xbl@rock-chips.com>
1 parent 56659dc commit 4532bf9

9 files changed

Lines changed: 838 additions & 0 deletions

File tree

drivers/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,6 @@ source "drivers/rk_nand/Kconfig"
204204

205205
source "drivers/headset_observe/Kconfig"
206206

207+
source "drivers/miniarm/Kconfig"
208+
207209
endmenu

drivers/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,5 @@ obj-$(CONFIG_NVMEM) += nvmem/
176176
obj-$(CONFIG_FPGA) += fpga/
177177
obj-$(CONFIG_RK_NAND) += rk_nand/
178178
obj-$(CONFIG_RK_HEADSET) += headset_observe/
179+
180+
obj-y += miniarm/

drivers/miniarm/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
source "drivers/miniarm/dsi/Kconfig"
2+
3+

drivers/miniarm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
obj-y += dsi/

drivers/miniarm/dsi/Kconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
config DRM_PANEL_TOSHIBA_TC358762
2+
tristate "support for toshiba tc358762"
3+
depends on OF && I2C
4+
depends on BACKLIGHT_CLASS_DEVICE
5+
select VIDEOMODE_HELPERS
6+
help
7+
Say Y here if you want to enable support for toshiba tc358762 bridge.
8+
To compile this driver as a module, choose M here.
9+
10+
config ASUS_RPI_MCU
11+
tristate "RPI MCU for ASUS"
12+
depends on DRM_ROCKCHIP && DRM_PANEL_TOSHIBA_TC358762
13+
depends on I2C
14+
select RPI_MCU
15+
help
16+
This selects support for TOSHIBA TC358762 bridge specific
17+
extensions for ASUS rpi. If you want to enable MIPI DSI
18+
on RK3288 based SoC, you should selet this option.

drivers/miniarm/dsi/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
obj-$(CONFIG_DRM_PANEL_TOSHIBA_TC358762) += panel-toshiba-tc358762.o
2+
obj-$(CONFIG_ASUS_RPI_MCU) += asus_mcu.o

drivers/miniarm/dsi/asus_mcu.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/*
2+
*
3+
* RPI Touchscreen MCU driver.
4+
*
5+
* Copyright (c) 2016 ASUSTek Computer Inc.
6+
* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
7+
*
8+
* This software is licensed under the terms of the GNU General Public
9+
* License version 2, as published by the Free Software Foundation, and
10+
* may be copied, distributed, and modified under those terms.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
*/
18+
19+
#include <linux/module.h>
20+
#include <linux/slab.h>
21+
#include <linux/delay.h>
22+
#include <linux/i2c.h>
23+
#include <linux/module.h>
24+
#include <linux/workqueue.h>
25+
#include "asus_mcu.h"
26+
27+
struct ts_mcu_data *mdata;
28+
29+
static int is_hex(char num)
30+
{
31+
//0-9, a-f, A-F
32+
if ((47 < num && num < 58) || (64 < num && num < 71) || (96 < num && num < 103))
33+
return 1;
34+
return 0;
35+
}
36+
37+
static int string_to_byte(const char *source, unsigned char *destination, int size)
38+
{
39+
int i = 0, counter = 0;
40+
char c[3] = {0};
41+
unsigned char bytes;
42+
43+
if (size%2 == 1)
44+
return -EINVAL;
45+
46+
for(i = 0; i < size; i++){
47+
if(!is_hex(source[i])) {
48+
return -EINVAL;
49+
}
50+
if(0 == i%2){
51+
c[0] = source[i];
52+
c[1] = source[i+1];
53+
sscanf(c, "%hhx", &bytes);
54+
destination[counter] = bytes;
55+
counter++;
56+
}
57+
}
58+
return 0;
59+
}
60+
61+
static int send_cmds(struct i2c_client *client, const char *buf)
62+
{
63+
int ret, size = strlen(buf);
64+
unsigned char byte_cmd[size/2];
65+
66+
if ((size%2) != 0) {
67+
LOG_ERR("size should be even\n");
68+
return -EINVAL;
69+
}
70+
71+
LOG_INFO("%s\n", buf);
72+
73+
string_to_byte(buf, byte_cmd, size);
74+
75+
ret = i2c_master_send(client, byte_cmd, size/2);
76+
if (ret < 0) {
77+
LOG_ERR("send command failed, ret = %d\n", ret);
78+
return ret;
79+
}
80+
81+
msleep(20);
82+
return 0;
83+
}
84+
85+
static int recv_cmds(struct i2c_client *client, char *buf, int size)
86+
{
87+
int ret;
88+
89+
ret = i2c_master_recv(client, buf, size);
90+
if (ret < 0) {
91+
LOG_ERR("receive commands failed, %d\n", ret);
92+
return ret;
93+
}
94+
msleep(20);
95+
return 0;
96+
}
97+
98+
static int init_cmd_check(struct ts_mcu_data *mcu_data)
99+
{
100+
int ret;
101+
char recv_buf[1] = {0};
102+
103+
ret = send_cmds(mcu_data->client, "80");
104+
if (ret < 0)
105+
goto error;
106+
107+
recv_cmds(mcu_data->client, recv_buf, 1);
108+
if (ret < 0)
109+
goto error;
110+
111+
LOG_INFO("recv_cmds: 0x%X\n", recv_buf[0]);
112+
if (recv_buf[0] != 0xC3) {
113+
LOG_ERR("read wrong info\n");
114+
ret = -EINVAL;
115+
goto error;
116+
117+
}
118+
return 0;
119+
120+
error:
121+
return ret;
122+
}
123+
124+
void mcu_power_up(void)
125+
{
126+
send_cmds(mdata->client, "8500");
127+
msleep(800);
128+
send_cmds(mdata->client, "8501");
129+
send_cmds(mdata->client, "86FF");
130+
send_cmds(mdata->client, "8104");
131+
}
132+
EXPORT_SYMBOL_GPL(mcu_power_up);
133+
134+
static int rpi_ts_mcu_probe(struct i2c_client *client,
135+
const struct i2c_device_id *id)
136+
{
137+
int ret;
138+
139+
LOG_INFO("address = 0x%x\n", client->addr);
140+
141+
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
142+
LOG_ERR("I2C check functionality failed\n");
143+
return -ENODEV;
144+
}
145+
146+
mdata = kzalloc(sizeof(struct ts_mcu_data), GFP_KERNEL);
147+
if (mdata == NULL) {
148+
LOG_ERR("no memory for device\n");
149+
return -ENOMEM;
150+
}
151+
152+
mdata->client = client;
153+
i2c_set_clientdata(client, mdata);
154+
155+
ret = init_cmd_check(mdata);
156+
if (ret < 0) {
157+
LOG_ERR("init_cmd_check failed, %d\n", ret);
158+
goto error;
159+
}
160+
161+
return 0;
162+
163+
error:
164+
kfree(mdata);
165+
return ret;
166+
}
167+
168+
static int rpi_ts_mcu_remove(struct i2c_client *client)
169+
{
170+
struct ts_mcu_data *mcu_data = i2c_get_clientdata(client);
171+
172+
kfree(mcu_data);
173+
return 0;
174+
}
175+
176+
static const struct i2c_device_id rpi_ts_mcu_id[] = {
177+
{"rpi_ts_mcu", 0},
178+
{},
179+
};
180+
181+
static struct i2c_driver rpi_ts_mcu_driver = {
182+
.driver = {
183+
.name = "rpi_ts_mcu",
184+
},
185+
.probe = rpi_ts_mcu_probe,
186+
.remove = rpi_ts_mcu_remove,
187+
.id_table = rpi_ts_mcu_id,
188+
};
189+
module_i2c_driver(rpi_ts_mcu_driver);
190+
191+
MODULE_DESCRIPTION("RPI TouchScreen MCU driver");
192+
MODULE_LICENSE("GPL v2");

drivers/miniarm/dsi/asus_mcu.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef _RPI_TS_MCU_H_
2+
#define _RPI_TS_MCU_H_
3+
4+
#define LOG_INFO(fmt,arg...) pr_info("%s: "fmt, __func__, ##arg);
5+
#define LOG_ERR(fmt,arg...) pr_err("%s: "fmt, __func__, ##arg);
6+
7+
#define MAX_I2C_LEN 255
8+
9+
struct ts_mcu_data {
10+
struct device *dev;
11+
struct i2c_client *client;
12+
struct delayed_work work;
13+
struct workqueue_struct *wq;
14+
};
15+
16+
#endif

0 commit comments

Comments
 (0)