1 // ****************************************** //
2 // access IIC, GPIO, etc. from user space by anli.wei
4 // 2013-01-22 add key info anli.wei
5 // ****************************************** //
7 #include <linux/cdev.h>
8 #include <linux/device.h>
9 #include <linux/errno.h>
10 #include <linux/fcntl.h>
12 #include <linux/i2c.h>
13 #include <linux/init.h>
14 #include <linux/input.h>
15 #include <linux/interrupt.h>
16 #include <linux/kernel.h>
17 #include <linux/major.h>
18 #include <linux/module.h>
19 #include <linux/types.h>
22 #include <asm/uaccess.h>
23 #include <soc/sprd/board.h>
24 #include <soc/sprd/gpio.h>
26 #include "autotstdrv.h"
29 #define DBG_ENABLE_FUN
30 #define DBG_ENABLE_INFO
33 #define FUN_ENTER printk(KERN_INFO "autotst-> %s ++.\n", __FUNCTION__)
34 #define FUN_LEAVE printk(KERN_INFO "autotst-> %s --.\n", __FUNCTION__)
36 #define FUN_ENTER do {} while(0)
37 #define FUN_LEAVE do {} while(0)
38 #endif // DBG_ENABLE_FUN
40 #ifdef DBG_ENABLE_INFO
41 #define DBG_INFO(fmt, arg...) printk(KERN_INFO "autotst-> " fmt, ##arg)
43 #define DBG_INFO(fmt, arg...) do {} while(0)
44 #endif // DBG_ENABLE_INFO
46 //------------------------------------------------------------------------------
47 //------------------------------------------------------------------------------
48 #define SPRD_MAX_PIN 200
49 #define SPRD_GPIO_PIN_INVALID_VALUE 0xFFFFFFFF
51 //static uint32_t sGpioPins[SPRD_MAX_PIN];
53 //------------------------------------------------------------------------------
54 //------------------------------------------------------------------------------
55 extern int lcm_init( void );
56 extern int32_t lcm_send_data (uint32_t data);
58 //------------------------------------------------------------------------------
59 #define CDEV_NAME "autotst"
62 static struct cdev s_cdev;
63 static struct class *s_class;
65 //------------------------------------------------------------------------------
67 static int autotst_open (struct inode *inode, struct file *filp)
74 static int autotst_release (struct inode *inode, struct file *filp)
81 //------------------------------------------------------------------------------
82 //------------------------------------------------------------------------------
84 static int i2c_read( struct autotst_i2c_info_t * info )
86 struct i2c_msg xfer[2];
87 u8 reg[2], reg_len = 0;
88 u8 addr = (info->addr >> 1);
91 struct i2c_adapter * adpt = i2c_get_adapter(info->bus);
93 printk(KERN_ERR "get adapter(%d) fail!\n", info->bus);
97 DBG_INFO("i2c read: bus = %d, addr = %X, reg = %X\n", info->bus, addr, info->reg);
99 if( 16 == info->regBits ) {
100 reg[reg_len++] = (u8)(info->reg >> 8);
102 reg[reg_len++] = (u8)(info->reg);
107 xfer[0].len = reg_len;
112 xfer[1].flags = I2C_M_RD;
113 xfer[1].len = info->data_len;
114 xfer[1].buf = info->data;
116 ret = i2c_transfer(adpt, xfer, 2);
118 printk(KERN_ERR "i2c_transfer() returned %d\n", ret);
120 i2c_put_adapter(adpt);
124 DBG_INFO("i2c read done: bus = %d, addr = 0x%04X, reg = 0x%04X\n",
125 info->bus, info->addr, info->reg);
127 i2c_put_adapter(adpt);
131 //------------------------------------------------------------------------------
132 static int i2c_write( struct autotst_i2c_info_t * info )
140 struct i2c_adapter * adpt = i2c_get_adapter(info->bus);
142 printk(KERN_ERR "get adapter(%d) fail!\n", info->bus);
146 if( 16 == info->regBits ) {
147 buf[num++] = (u8)(info->reg >> 8);
150 buf[num++] = (u8)(info->reg);
152 for( i = 0; i < info->data_len; ++i )
154 buf[num++] = info->data[i];
157 xfer.addr = info->addr;
162 ret = i2c_transfer(adpt, &xfer, 1);
164 printk(KERN_ERR "i2c_transfer() returned %d\n", ret);
166 i2c_put_adapter(adpt);
170 DBG_INFO("i2c write done: bus = %d, addr = 0x%04X, reg = 0x%04X\n",
171 info->bus, info->addr, info->reg);
173 i2c_put_adapter(adpt);
177 //------------------------------------------------------------------------------
178 static int i2c_ioctl( unsigned int cmd, unsigned long arg )
181 struct autotst_i2c_info_t iit;
183 if( copy_from_user(&iit, (const void __user *)arg, sizeof(struct autotst_i2c_info_t)) ) {
184 printk(KERN_ERR "copy_from_user fail: arg = %lu\n", arg);
189 case AUTOTST_IOCTL_I2C_READ:
190 ret = i2c_read( &iit );
192 if( copy_to_user((void __user *)arg, &iit, sizeof(struct autotst_i2c_info_t)) ) {
193 printk(KERN_ERR "copy_to_user fail: arg = %lu\n", arg);
198 case AUTOTST_IOCTL_I2C_WRITE:
199 ret = i2c_write( &iit );
208 //------------------------------------------------------------------------------
209 //------------------------------------------------------------------------------
211 static int gpio_ioctl( unsigned int cmd, unsigned long arg )
214 struct autotst_gpio_info_t git;
216 if( copy_from_user(&git, (const void __user *)arg, sizeof(struct autotst_gpio_info_t)) ) {
217 printk(KERN_ERR "copy_from_user fail: arg = %lu\n", arg);
222 case AUTOTST_IOCTL_GPIO_INIT:
225 snprintf(name, 32, "at_gio_%d", git.gpio);
226 /* // not support, already config on platform
232 gpio_request(git.gpio, name);
233 if( AUTOTST_GPIO_DIR_IN == git.dir ) {
234 gpio_direction_input(git.gpio);
236 gpio_direction_output(git.gpio, git.val);
240 case AUTOTST_IOCTL_GPIO_GET: {
241 int gv = gpio_get_value(git.gpio);
243 git.val = (gv > 0) ? 1 : 0;
244 if( copy_to_user((void __user *)arg, &git, sizeof(struct autotst_gpio_info_t)) ) {
245 printk(KERN_ERR "copy_to_user fail: arg = %lu\n", arg);
250 case AUTOTST_IOCTL_GPIO_SET:
251 gpio_set_value(git.gpio, git.val);
260 //------------------------------------------------------------------------------
261 //------------------------------------------------------------------------------
263 static int key_ioctl( unsigned int cmd, unsigned long arg )
266 struct autotst_key_info_t kit;
268 if( copy_from_user(&kit, (const void __user *)arg, sizeof(struct autotst_key_info_t)) ) {
269 printk(KERN_ERR "copy_from_user fail: arg = %lu\n", arg);
273 if( KEY_POWER == kit.val ) {
274 kit.row = AUTOTST_KEY_INVALID_ROW;
275 kit.col = AUTOTST_KEY_INVALID_COL;
276 kit.gio = EIC_KEY_POWER;
278 unsigned char rc = (kit.val & 0xF7);
280 kit.row = ((rc >> 4) & 0x0F);
281 kit.col = ((rc >> 0) & 0x0F);
286 if( copy_to_user((void __user *)arg, &kit, sizeof(struct autotst_key_info_t)) ) {
287 printk(KERN_ERR "copy_to_user fail: arg = %lu\n", arg);
295 //------------------------------------------------------------------------------
296 //------------------------------------------------------------------------------
298 static long autotst_ioctl( struct file *filp, unsigned int cmd, unsigned long arg )
304 DBG_INFO("cmd = 0x%X\n", cmd);
306 case AUTOTST_IOCTL_I2C_READ:
307 case AUTOTST_IOCTL_I2C_WRITE:
308 ret = i2c_ioctl(cmd, arg);
310 case AUTOTST_IOCTL_GPIO_INIT:
311 case AUTOTST_IOCTL_GPIO_GET:
312 case AUTOTST_IOCTL_GPIO_SET:
313 ret = gpio_ioctl(cmd, arg);
315 case AUTOTST_IOCTL_LCD_DATA:
318 DBG_INFO("lcd data = 0x%X\n", (uint32_t)arg);
321 for( i = 0; i < 32; ++i ) {
322 lcm_send_data((uint32_t)arg);
325 autotst_dispc_init(DISPLAY_TYPE_MCU);
326 for( i = 0; i < 32; ++i ) {
327 autotst_dispc_mcu_send_data((uint32_t)arg);
329 autotst_dispc_uninit(DISPLAY_TYPE_MCU);
335 case AUTOTST_IOCTL_LCD_MIPI_ON:
338 DBG_INFO("lcd mipi on\n");
339 autotst_dispc_init(DISPLAY_TYPE_MIPI);
340 autotst_dispc_refresh();
344 case AUTOTST_IOCTL_LCD_MIPI_OFF:
347 DBG_INFO("lcd mipi off\n");
348 autotst_dispc_uninit(DISPLAY_TYPE_MIPI);
353 case AUTOTST_IOCTL_GET_KEYINFO:
354 ret = key_ioctl(cmd, arg);
358 DBG_INFO("lcd default \n");
366 static struct file_operations autotst_fops =
368 .owner = THIS_MODULE,
369 .unlocked_ioctl = autotst_ioctl,
370 .open = autotst_open,
371 .release = autotst_release,
374 //==============================================================================
376 static int __init autotst_init(void)
382 // auto select a major
383 ret = alloc_chrdev_region(&s_devt, 0, 1, CDEV_NAME);
385 printk(KERN_ERR "ERROR: alloc_chrdev_region %d\n", ret);
389 cdev_init(&s_cdev, &autotst_fops);
390 ret = cdev_add(&s_cdev, s_devt, 1);
393 unregister_chrdev_region(s_devt, 1);
394 printk(KERN_ERR "ERROR: cdev_add %d\n", ret);
398 s_class = class_create(THIS_MODULE, CDEV_NAME);
399 device_create(s_class, NULL, MKDEV(MAJOR(s_devt), MINOR(s_devt)), NULL, CDEV_NAME);
401 // autotst_dispc_pin_ctrl(DISPC_PIN_FUNC3);
403 //for( i = 0; i < SPRD_MAX_PIN; ++i ) {
404 // sGpioPins[i] = SPRD_GPIO_PIN_INVALID_VALUE;
406 //sGpioPins[59] = MFP_CFG_X(SIMCLK3, AF3, DS1, F_PULL_NONE, S_PULL_NONE, IO_OE);
412 static void __exit autotst_exit(void)
416 device_destroy(s_class, MKDEV(MAJOR(s_devt), MINOR(s_devt)));
417 class_destroy(s_class);
420 unregister_chrdev_region(s_devt, 1);
422 // autotst_dispc_pin_ctrl(DISPC_PIN_FUNC0);
427 module_init(autotst_init);
428 module_exit(autotst_exit);
430 MODULE_LICENSE("Dual BSD/GPL");
431 MODULE_AUTHOR("anli.wei");
432 MODULE_VERSION("0.0.1");