Chinaunix首页 | 论坛 | 博客
  • 博客访问: 19870
  • 博文数量: 13
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 75
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-03 13:44
文章存档

2012年(13)

我的朋友

分类:

2012-06-03 20:41:55

android启动过程配置文件的解析与语法

(1)android启动文件系统后调用的第一个应用程序是/init,此文件的很重要的内容是解析了init.rcinit.xxx.rc
两个配置文件,然后执行解析出来的任务。相关代码在android源代码/system/core/init/init.c文件中,如下:
    parse_config_file("/init.rc");

    /* pull the kernel commandline and ramdisk properties file in */
    qemu_init();
    import_kernel_cmdline(0);

    get_hardware_name();
    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
    parse_config_file(tmp);

(2)
从上面代码可以看到,第一个配置文件名称固定为init.rc,而第二个配置文件格式为init.xxx.rc,其中xxx部分的内容
是从内核读取的,具体是读取文件/proc/cpuinfo中的Hardware部分,然后截取其部分内容。Hardware部分是定义在内核的
主板定义文件中,我的平台是定义在内核arch/arm/mach-mmp/merlin.c中,我的平台定义如下:
MACHINE_START(ARDENT_MERLIN, "PXA168-based Merlin Platform")
    .phys_io = APB_PHYS_BASE,
    .boot_params = 0x00000100,
    .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
    .map_io = pxa_map_io,
    .init_irq = pxa168_init_irq,
    .timer = &pxa168_timer,
    .init_machine = merlin_init,
MACHINE_END
这样截取到的hardware部分的内容就为pxa168-based,也就是说我的平台的第二个配置文件应该命名为init.pxa168-based.rc

(3)
从上面看init.xxx.rc中的xxx内容是取决是内核中主板的定义的,如果觉得麻烦,可以将其在代码中写死,例如:
    parse_config_file(“init.merlin.rc”);

(4)
配置文件的语法如下:
(a)
配置文件的内容包含有4种:
    
动作(Action)
    
命令(Commands)
    
服务(Services)
    
选项(Options)
(b)
动作和命令一起使用,形式如下:
on
 
 
 
其中trigger是触发条件,也就是说在满足触发条件的情况下执行1个或多个相应的命令,举例如下:
on property:persist.service.adb.enable=1
    start adbd

(c)
服务和选项一起使用,形式如下:
  service [ ]*
 
上面内容解释为:
  service
服务名称 服务对应的命令的路径 命令的参数
   
选项
   
选项
  ...
举例如下:
service ril-daemon /system/bin/rild
    socket rild stream 660 root radio
    socket rild-debug stream 660 radio system
    user root
    group radio cache inet misc audio
上面的服务对应到/system/bin/rild命令,没有参数,服务名称为ril-daemon,后面的内容都是服务的选项。

(d)
选项是影响服务启动和运行的参数,主要的选项如下:

disabled 
禁用服务,此服务开机时不会自动启动,但是可以在应用程序中手动启动它。

socket [ [ ] ]
套接字    类型        名称           权限           用户           组
创建一个名为/dev/socket/,然后把它的fd传给启动程序
类型type的值为dgram或者stream
perm
表示该套接字的访问权限,usergroup表示改套接字所属的用户和组,这两个参数默认都是0,因此可以不设置。

user
执行服务前切换到用户,此选项默认是root,因此可以不设置。

group [ ]*
执行服务前切换到组,此选项默认是root,因此可以不设置

capability [ ]+
执行服务前设置linux capability,没什么用。

oneshot
服务只启动一次,一旦关闭就不能再启动。

class
为服务指定一个类别,默认为"default",同一类别的服务必须一起启动和停止

(e)
动作触发条件
boot 
首个触发条件,初始化开始(载入配置文件)的时候触发

=
当名为的属性(property)的值为的时候触发

device-added-
路径为的设置添加的时候触发

device-removed-
路径为的设置移除的时候触发

service-exited-
名为的服务关闭的时候触发

(f)
命令(Command)的形式
exec [ ]*
复制(fork)和执行路径为的应用程序,为该应用程序的参数,在该应用程序执行完前,此命令会屏蔽,

export
声明名为的环境变量的值为,声明的环境变量是系统环境变量,启动后一直有效。

ifup
启动名为的网络接口

import
加入新的位置文件,扩展当前的配置。

hostname
设置主机名

class_start
启动指定类别的所有服务

class_stop
停止指定类别的所有服务

domainname
设置域名

insmod
加载路径为的内核模块

mkdir
创建路径为目录

mount

[ ]*
挂载类型为的设备到目录,为挂载参数,距离如下:
    mount ubifs ubi1_0 /data nosuid nodev

setkey
暂时未定义

setprop
设置名为的系统属性的值为

setrlimit
设置资源限制,举例:
# set RLIMIT_NICE to allow priorities from 19 to -20
    setrlimit 13 40 40
没看懂是什么意思。

start
启动服务(如果服务未运行)

stop
停止服务(如果服务正在运行)

symlink
创建一个从指向的符号链接,举例:
    symlink /system/etc /etc

write [ ]*
打开路径为的文件并将一个多这多个字符串写入到该文件中。

(g)
系统属性(Property)
android
初始化过程中会修改一些属性,通过getprop命令我们可以看到属性值,这些属性指示了某些动作或者服务的状态,主要如下:
init.action     
如果当前某个动作正在执行则init.action属性的值等于该动作的名称,否则为""
init.command    
如果当前某个命令正在执行则init.command属性的值等于该命令的名称,否则为""
init.svc. 
此属性指示个名为的服务的状态("stopped", "running", 或者 "restarting").

android系统开发()-触摸屏tslib移植(内核)和原理分析

首先了解一下tslib的运行原理,tslib的运行分成两部分
(1)
校验
LCD固定坐标位置依次显示出5个坐标让用户触摸,把LCD坐标和用户触摸时驱动屏驱动底层的坐标总共5组值保存起来
运行tslib库的算法对其进行运算,得出校准用7个值

(2)
校准
每次触摸屏驱动读取到硬件坐标时应用校准用的7个值对该坐标进行一次运算,然后将运算后的坐标作为正常坐标即可。

按照上面的原理,
(1)
我们先修改内核部分,我的平台用的触摸屏幕驱动是tsc2007,驱动文件为内核/drivers/input/touchscreen
目录下的tsc2007.cts_linear.c
其中,ts_linear.c中定义的是校准模块,该模块在proc文件系统中建立了7个文件,用来存放校准用的7个点,7的点的默认值
1,0,0,0,1,0,1,对应的目标平台文件系统的位置为/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a67个文件
此模块中还定义了一个校准函数ts_linear_scale,此函数的主要内容是读取a0,a1,a2,a3,a4,a5,a67个文件中的值作为7
校准值与传入的触摸平坐标值进行运算,返回运算结果。
ts_linear_scale
函数定义如下:
int ts_linear_scale(int *x, int *y, int swap_xy)
{
    int xtemp, ytemp;

    xtemp = *x;
    ytemp = *y;

    if (cal.a[6] == 0)
        return -EINVAL;

    *x = (cal.a[2] + cal.a[0] * xtemp + cal.a[1] * ytemp) / cal.a[6];
    *y = (cal.a[5] + cal.a[3] * xtemp + cal.a[4] * ytemp) / cal.a[6];

    if (swap_xy) {
        int tmp = *x;
        *x = *y;
        *y = tmp;
    }
    return 0;
}

ts2007.c为触摸屏驱,与其他驱动不同的地方是在取得硬件坐标值发送之前先调用了ts_linear_scale函数对坐标值进行了校准
            if (x > 0 && y > 0)
            {
                ts_linear_scale(&x, &y, invert);
                input_report_abs(input, ABS_X, x);
                input_report_abs(input, ABS_Y, y);
                input_report_abs(input, ABS_PRESSURE, 255);
                input_report_abs(input, ABS_TOOL_WIDTH, 1);
                input_report_key(input, BTN_TOUCH, 1);
                input_sync(input);
            }

(2)
android源代码/system/core/rootdir/init.rc文件中添加tslib相关的宏定义如下:
# touchscreen parameters
    export TSLIB_FBDEVICE /dev/graphics/fb0
    export TSLIB_CALIBFILE /data/etc/pointercal
    export TSLIB_CONFFILE  /system/etc/ts.conf
    export TSLIB_TRIGGERDEV /dev/input/event0
    export TSLIB_TSDEVICE /dev/input/event1

(2)
移植tslib库到android系统,比较麻烦,看下一节的内容。

(3)
校验程序完成后会将生成的7个校准值写入到环境变量TSLIB_CALIBFILE对应的路径/data/etc/pointercal文件中

(4)
校验完后将pointercal文件中的7个值分别写入到/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6文件即可。

(5)
开机启动的时候我们编写一个应用程序,首先判断环境变量TSLIB_CALIBFILE对应的路径/data/etc/pointercal文件是否存在,如果
文件存在而且非空,则将该文件中的7个值取出来分别写入到/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6文件

(6)
为了确保未校验前触摸屏可用,我们将一次校验后得出的7个坐标值作为初始值,修改到内核ts_linear.c文件中。

下面是源代码:
ts_linear.c
文件
/*
 *  Touchscreen Linear Scale Adaptor
 *
 *  Copyright (C) 2009 Marvell Corporation
 *
 *  Author: Mark F. Brown
 *  Based on tslib 1.0 plugin linear.c by Russel King
 *
 * This library is licensed under GPL.
 *
 */

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

/*
 * sysctl-tuning infrastructure.
 */
static struct ts_calibration {
/* Linear scaling and offset parameters for x,y (can include rotation) */
    int a[7];
} cal;

static ctl_table ts_proc_calibration_table[] = {
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "a0",
     .data = &cal.a[0],
     .maxlen = sizeof(int),
     .mode = 0666,
     .proc_handler = &proc_dointvec,
     },
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "a1",
     .data = &cal.a[1],
     .maxlen = sizeof(int),
     .mode = 0666,
     .proc_handler = &proc_dointvec,
     },
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "a2",
     .data = &cal.a[2],
     .maxlen = sizeof(int),
     .mode = 0666,
     .proc_handler = &proc_dointvec,
     },
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "a3",
     .data = &cal.a[3],
     .maxlen = sizeof(int),
     .mode = 0666,
     .proc_handler = &proc_dointvec,
     },
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "a4",
     .data = &cal.a[4],
     .maxlen = sizeof(int),
     .mode = 0666,
     .proc_handler = &proc_dointvec,
     },
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "a5",
     .data = &cal.a[5],
     .maxlen = sizeof(int),
     .mode = 0666,
     .proc_handler = &proc_dointvec,
     },
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "a6",
     .data = &cal.a[6],
     .maxlen = sizeof(int),
     .mode = 0666,
     .proc_handler = &proc_dointvec,
     },

    {.ctl_name = 0}
};

static ctl_table ts_proc_root[] = {
    {
     .ctl_name = CTL_UNNUMBERED,
     .procname = "ts_device",
     .mode = 0555,
     .child = ts_proc_calibration_table,
     },
    {.ctl_name = 0}
};

static ctl_table ts_dev_root[] = {
    {
     .ctl_name = CTL_DEV,
     .procname = "dev",
     .mode = 0555,
     .child = ts_proc_root,
     },
    {.ctl_name = 0}
};

static struct ctl_table_header *ts_sysctl_header;

int ts_linear_scale(int *x, int *y, int swap_xy)
{
    int xtemp, ytemp;

    xtemp = *x;
    ytemp = *y;

    if (cal.a[6] == 0)
        return -EINVAL;

    *x = (cal.a[2] + cal.a[0] * xtemp + cal.a[1] * ytemp) / cal.a[6];
    *y = (cal.a[5] + cal.a[3] * xtemp + cal.a[4] * ytemp) / cal.a[6];

    if (swap_xy) {
        int tmp = *x;
        *x = *y;
        *y = tmp;
    }
    return 0;
}

EXPORT_SYMBOL(ts_linear_scale);

static int __init ts_linear_init(void)
{
    ts_sysctl_header = register_sysctl_table(ts_dev_root);
    /* Use default values that leave ts numbers unchanged after transform */
    cal.a[0] = 1;
    cal.a[1] = 0;
    cal.a[2] = 0;
    cal.a[3] = 0;
    cal.a[4] = 1;
    cal.a[5] = 0;
    cal.a[6] = 1;
    return 0;
}

static void __exit ts_linear_cleanup(void)
{
    unregister_sysctl_table(ts_sysctl_header);
}

module_init(ts_linear_init);
module_exit(ts_linear_cleanup);

MODULE_DESCRIPTION("touch screen linear scaling driver");
MODULE_LICENSE("GPL");



ts2007.c
文件
/*
 *  linux/drivers/input/touchscreen/tsc2007.c
 *
 *  touch screen driver for tsc2007
 *
 *  Copyright (C) 2006, Marvell Corporation
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 */

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
#include

extern int ts_linear_scale(int *x, int *y, int swap_xy);

/* Use MAV filter */
#define TSC_CMD_SETUP 0xb0

/* Use 12-bit */
#define TSC_CMD_X 0xc0
#define TSC_CMD_PLATEX 0x80
#define TSC_CMD_Y 0xd0
#define TSC_CMD_PLATEY 0x90

#define TSC_X_MAX 4096
#define TSC_Y_MAX 4096
#define TSC_X_MIN 0
#define TSC_Y_MIN 0

/* delay time for compute x, y, computed as us */

#define DEBUG
#ifdef DEBUG
#define TS_DEBUG(fmt,args...) printk(KERN_DEBUG fmt, ##args )
#else
#define TS_DEBUG(fmt,args...)
#endif
static int x_min=TSC_X_MIN;
static int y_min=TSC_Y_MIN;
static int x_max=TSC_X_MAX;
static int y_max=TSC_Y_MAX;
static int invert = 0;
static int debounce_time  = 150;
static int init_debounce = true;
static int delay_time = 1;

enum tsc2007_status {
    PEN_UP,
    PEN_DOWN,
};

struct _tsc2007 {
    struct input_dev *dev;
    int x;        /* X sample values */
    int y;        /* Y sample values */

    int status;
    struct work_struct irq_work;
    struct i2c_client *client;
    unsigned long last_touch;
};
struct _tsc2007 *g_tsc2007;

/* update abs params when min and max coordinate values are set */
int tsc2007_proc_minmax(struct ctl_table *table, int write, struct file *filp,
                     void __user *buffer, size_t *lenp, loff_t *ppos)
{
    struct _tsc2007 *tsc2007= g_tsc2007;
    struct input_dev *input = tsc2007->dev;

    /* update value */
    int ret = proc_dointvec(table, write, filp, buffer, lenp, ppos);

    /* updated abs params */
    if (input) {
        TS_DEBUG(KERN_DEBUG "update x_min %d x_max %d"
            " y_min %d y_max %d\n", x_min, x_max,
            y_min, y_max);
        input_set_abs_params(input, ABS_X, x_min, x_max, 0, 0);
        input_set_abs_params(input, ABS_Y, y_min, y_max, 0, 0);
    }
    return ret;
}

static ctl_table tsc2007_proc_table[] = {
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "x-max",
        .data        = &x_max,
        .maxlen        = sizeof(int),
        .mode        = 0666,
        .proc_handler    = &tsc2007_proc_minmax,
    },
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "y-max",
        .data        = &y_max,
        .maxlen        = sizeof(int),
        .mode        = 0666,
        .proc_handler    = &tsc2007_proc_minmax,
    },
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "x-min",
        .data        = &x_min,
        .maxlen        = sizeof(int),
        .mode        = 0666,
        .proc_handler    = &tsc2007_proc_minmax,
    },
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "y-min",
        .data        = &y_min,
        .maxlen        = sizeof(int),
        .mode        = 0666,
        .proc_handler    = &tsc2007_proc_minmax,
    },
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "invert_xy",
        .data        = &invert,
        .maxlen        = sizeof(int),
        .mode        = 0666,
        .proc_handler    = &proc_dointvec,
    },
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "debounce_time",
        .data        = &debounce_time,
        .maxlen        = sizeof(int),
        .mode        = 0666,
        .proc_handler    = &proc_dointvec,
    },
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "delay_time",
        .data        = &delay_time,
        .maxlen        = sizeof(int),
        .mode        = 0666,
        .proc_handler    = &proc_dointvec,
    },
    { .ctl_name = 0 }
};

static ctl_table tsc2007_proc_root[] = {
    {
        .ctl_name    = CTL_UNNUMBERED,
        .procname    = "ts_device",
        .mode        = 0555,
        .child        = tsc2007_proc_table,
    },
    { .ctl_name = 0 }
};

static ctl_table tsc2007_proc_dev_root[] = {
    {
        .ctl_name    = CTL_DEV,
        .procname    = "dev",
        .mode        = 0555,
        .child        = tsc2007_proc_root,
    },
    { .ctl_name = 0 }
};

static struct ctl_table_header *sysctl_header;

static int __init init_sysctl(void)
{
    sysctl_header = register_sysctl_table(tsc2007_proc_dev_root);
    return 0;
}

static void __exit cleanup_sysctl(void)
{
    unregister_sysctl_table(sysctl_header);
}

static int tsc2007_measure(struct i2c_client *client, int *x, int * y)
{
    u8 x_buf[2] = {0, 0};
    u8 y_buf[2] = {0, 0};

    i2c_smbus_write_byte(client, TSC_CMD_PLATEX);
    msleep_interruptible(delay_time);

    i2c_smbus_write_byte(client, TSC_CMD_X);
    i2c_master_recv(client, x_buf, 2);
    *x = (x_buf[0]<<4) | (x_buf[1] >>4);

    i2c_smbus_write_byte(client, TSC_CMD_PLATEY);
    msleep_interruptible(delay_time);

    i2c_smbus_write_byte(client, TSC_CMD_Y);
    i2c_master_recv(client, y_buf, 2);
    *y = (y_buf[0]<<4) | (y_buf[1] >>4);
    *y = 4096 - *y; //added by allen
    printk("\ntouchscreen x = 0x%x, y = 0x%x\n",*x,*y);
    return 0;
}

static void tsc2007_irq_work(struct work_struct *work)
{
    struct _tsc2007 *tsc2007= g_tsc2007;
    struct i2c_client *client = tsc2007-> client;
    struct input_dev *input = tsc2007->dev;

    int x = -1, y = -1, is_valid = 0;
    int tmp_x = 0, tmp_y = 0;

    int gpio = irq_to_gpio(client->irq);


    /* Ignore if PEN_DOWN */
    if(PEN_UP == tsc2007->status){

        if (gpio_request(gpio, "tsc2007 touch detect")) {
            printk(KERN_ERR "Request GPIO failed, gpio: %X\n", gpio);
            return;
        }
        gpio_direction_input(gpio);   
       
        while(0 == gpio_get_value(gpio)){

                        if ((jiffies_to_msecs(
                                ((long)jiffies - (long)tsc2007->last_touch)) <
                 debounce_time &&
                tsc2007->status == PEN_DOWN) ||
                init_debounce)
                        {
                init_debounce = false;
                                tsc2007_measure(client, &tmp_x, &tmp_y);
                                TS_DEBUG(KERN_DEBUG
                "dropping pen touch %lu %lu (%u)\n",
                                jiffies, tsc2007->last_touch,
                                jiffies_to_msecs(
                (long)jiffies - (long)tsc2007->last_touch));
                                schedule();
                continue;
                        }


            /* continue report x, y */
            if (x > 0 && y > 0)
            {
                ts_linear_scale(&x, &y, invert);
                input_report_abs(input, ABS_X, x);
                input_report_abs(input, ABS_Y, y);
                input_report_abs(input, ABS_PRESSURE, 255);
                input_report_abs(input, ABS_TOOL_WIDTH, 1);
                input_report_key(input, BTN_TOUCH, 1);
                input_sync(input);
            }

            tsc2007->status = PEN_DOWN;
            tsc2007_measure(client, &x, &y);
            TS_DEBUG(KERN_DEBUG "pen down x=%d y=%d!\n", x, y);
            is_valid = 1;
            schedule();
        }

        if (is_valid)
        {
            /*consider PEN_UP */
            tsc2007->status = PEN_UP;
            input_report_abs(input, ABS_PRESSURE, 0);
            input_report_abs(input, ABS_TOOL_WIDTH, 1);
            input_report_key(input, BTN_TOUCH, 0);
            input_sync(input);
            tsc2007->last_touch = jiffies;
            TS_DEBUG(KERN_DEBUG "pen up!\n");
        }

        gpio_free(gpio);   
    }
}

static irqreturn_t tsc2007_interrupt(int irq, void *dev_id)
{   
    schedule_work(&g_tsc2007->irq_work);
   
    return IRQ_HANDLED;
}

static int __devinit tsc2007_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
{
    struct _tsc2007 *tsc2007;
    struct input_dev *input_dev;
    int ret;

    tsc2007 = kzalloc(sizeof(struct _tsc2007), GFP_KERNEL);
    input_dev = input_allocate_device();

    g_tsc2007 = tsc2007;

    if (!tsc2007 || !input_dev) {
        ret = -ENOMEM;
        goto fail1;
    }

    i2c_set_clientdata(client, tsc2007);

    tsc2007->dev = input_dev;

    input_dev->name = "tsc2007";
    input_dev->phys = "tsc2007/input0";

    //input_dev->id.bustype = BUS_HOST;
    input_dev->dev.parent = &client->dev;

    __set_bit(EV_KEY, input_dev->evbit);
    __set_bit(BTN_TOUCH, input_dev->keybit);

    __set_bit(EV_ABS, input_dev->evbit);
    __set_bit(ABS_PRESSURE, input_dev->evbit);
    __set_bit(ABS_X, input_dev->evbit);
    __set_bit(ABS_Y, input_dev->evbit);

    input_set_abs_params(input_dev, ABS_X, x_min, x_max, 0, 0);
    input_set_abs_params(input_dev, ABS_Y, y_min, y_max, 0, 0);
    input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);

    ret = request_irq(client->irq, tsc2007_interrupt,
        IRQF_DISABLED | IRQF_TRIGGER_FALLING,
         "tsc2007 irq", NULL);
    if (ret){
        printk(KERN_ERR "tsc2007 request irq failed\n");
        goto fail2;
    }

    ret = input_register_device(tsc2007->dev);
    if (ret){
        printk(KERN_ERR "tsc2007 register device fail\n");
        goto fail2;
    }

    /*init */
    tsc2007->status = PEN_UP;
    tsc2007->client = client;
    tsc2007->last_touch = jiffies;

    INIT_WORK(&tsc2007->irq_work, tsc2007_irq_work);

    /* init tsc2007 */
    i2c_smbus_write_byte(client, TSC_CMD_SETUP);

    return 0;

 fail2:
    free_irq(client->irq, client);
 fail1:
    i2c_set_clientdata(client, NULL);
    input_free_device(input_dev);
    kfree(tsc2007);
    return ret;
}

static int __devexit tsc2007_remove(struct i2c_client *client)
{
    struct _tsc2007 *tsc2007 = i2c_get_clientdata(client);

    if(client->irq)
        free_irq(client->irq, client);
   
    i2c_set_clientdata(client, NULL);
    input_unregister_device(tsc2007->dev);
    kfree(tsc2007);

    return 0;
}

static struct i2c_device_id tsc2007_idtable[] = {
    { "tsc2007", 0 },
    { }
};

MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);

static struct i2c_driver tsc2007_driver = {
    .driver = {
        .name     = "tsc2007",
    },
    .id_table       = tsc2007_idtable,
    .probe        = tsc2007_probe,
    .remove        = __devexit_p(tsc2007_remove),
};

static int __init tsc2007_ts_init(void)
{
    init_sysctl();
    return i2c_add_driver(&tsc2007_driver);     
}

static void __exit tsc2007_ts_exit(void)
{
    cleanup_sysctl();
    i2c_del_driver(&tsc2007_driver);
}

module_init(tsc2007_ts_init);
module_exit(tsc2007_ts_exit);

MODULE_DESCRIPTION("tsc2007 touch screen driver");
MODULE_LICENSE("GPL");

android系统开发()-tslib移植

(1)切换至tslib目录然后执行如下命令(marvell平台为例)
./autogen.sh
echo "ac_cv_func_malloc_0_nonnull=yes" > arm-marvell-linux.cache
./configure --host=arm-marvell-linux-gnueabi --prefix=/work/svn/ts_build --cache-file=arm-marvell-linux.cache
上面三步仅仅是为了取得tslib目录下的config.h文件

(2)
tslib复制到android源代码vendor//目录下

(3)
修改vendor//目录下的AndroidBoard.mk文件,加入如下内容
include $(LOCAL_PATH)/tslib/Mdroid.mk
一定要主义LOCAL_PATH这个宏的时效性

(4)
tslib目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

TS_PATH := $(LOCAL_PATH)

include $(TS_PATH)/src/Mdroid.mk
include $(TS_PATH)/plugins/Mdroid.mk
include $(TS_PATH)/tests/Mdroid.mk

include $(CLEAR_VARS)
file := $(TARGET_OUT_ETC)/ts.conf
$(file) : $(TS_PATH)/etc/ts.conf | $(ACP)
    $(transform-prebuilt-to-target)
ALL_PREBUILT += $(file)


(5)
tslib/src目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= ts_attach.c ts_close.c ts_config.c \
    ts_error.c ts_fd.c ts_load_module.c ts_open.c ts_parse_vars.c \
    ts_read.c ts_read_raw.c ts_option.c

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/../

LOCAL_SHARED_LIBRARIES += libutils libcutils

LOCAL_SHARED_LIBRARIES += libdl
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libts

include $(BUILD_SHARED_LIBRARY)


(6)
tslib/plugins目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= input-raw.c

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/../ \
        $(LOCAL_PATH)/../src

LOCAL_SHARED_LIBRARIES := libts
LOCAL_MODULE := input
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_SRC_FILES:= pthres.c

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/../ \
        $(LOCAL_PATH)/../src

LOCAL_SHARED_LIBRARIES := libts
LOCAL_MODULE := pthres
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_SRC_FILES:= variance.c

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/../ \
        $(LOCAL_PATH)/../src

LOCAL_SHARED_LIBRARIES := libts
LOCAL_MODULE := variance
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)


include $(CLEAR_VARS)
LOCAL_SRC_FILES:= dejitter.c

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/../ \
        $(LOCAL_PATH)/../src

LOCAL_SHARED_LIBRARIES := libts
LOCAL_MODULE := dejitter
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SRC_FILES:= linear.c

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/../ \
        $(LOCAL_PATH)/../src

LOCAL_SHARED_LIBRARIES := libts
LOCAL_MODULE := linear
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)


(7)
tslib/tests目录下创建Mdroid.mk,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= ts_calibrate.c fbutils.c testutils.c font_8x8.c font_8x16.c

LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/../ \
        $(LOCAL_PATH)/../src

LOCAL_SHARED_LIBRARIES := libts

LOCAL_SHARED_LIBRARIES += libutils libcutils

LOCAL_MODULE := tscalibrate

include $(BUILD_EXECUTABLE)


(8)
tslib/config.h文件中加入如下定义:
#define TS_CONF  "/system/etc/ts.conf"
#define PLUGIN_DIR "/system/lib"
#define TS_POINTERCAL "/data/etc/pointercal"


(9)
将下面路径文件
tslib/src/ts_open.c
tslib/tests/ts_calibrate.c
tslib/tests/fbutils.c
中的
#include
修改成
#include

(10)
tslib/tests/ts_calibrate.c文件中
static int clearbuf(struct tsdev *ts)
修改为
static void clearbuf(struct tsdev *ts)

(11)
修改tslib/etc/ts.conf内容如下:
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear

(12)
android源代码init.rc中声明tslib相关的宏如下:
# touchscreen parameters
    export TSLIB_FBDEVICE /dev/graphics/fb0
    export TSLIB_CALIBFILE /data/etc/pointercal
    export TSLIB_CONFFILE  /system/etc/ts.conf
    export TSLIB_TRIGGERDEV /dev/input/event0
    export TSLIB_TSDEVICE /dev/input/event1

(13)
重新编译后即可调用tscalibrate命令来校验触摸屏,校验后产生一个/data/etc/pointercal文件

阅读(1276) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~