⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hx4700_ts.c

📁 pocket pc hx4700 linux driver
💻 C
📖 第 1 页 / 共 2 页
字号:
    ts->input->absmax[ABS_X]        = 32767;    ts->input->absmin[ABS_Y]        = 0;    ts->input->absmax[ABS_Y]        = 32767;    ts->input->absmin[ABS_PRESSURE] = 0;    ts->input->absmax[ABS_PRESSURE] = 1;    ts->input->keybit[LONG(_KEY_RECORD)]   |= BIT(_KEY_RECORD); /* record */    ts->input->keybit[LONG(_KEY_CALENDAR)] |= BIT(_KEY_CALENDAR);  /* calendar */    ts->input->keybit[LONG(_KEY_HOMEPAGE)] |= BIT(_KEY_HOMEPAGE);    ts->input->name = "hx4700_ts";    ts->input->private = ts;    input_register_device(ts->input);    ts->timer.function = ts_timer_callback;    ts->timer.data = (unsigned long)ts;    ts->state = STATE_WAIT_FOR_TOUCH;    init_timer (&ts->timer);    INIT_WORK(&serial_work, start_read, ts);    dev_set_drvdata(dev, ts);    /* *** Initialize the SSP interface *** */    ssp_init();    down(&serial_mutex);    /* Make sure the device is in such a state that it can give pen     * interrupts. */    while(!(SSSR_P2 & (1 << 2)))        ;    SSDR_P2 = 0xd00000;    for(retval = 0; retval < 100; retval++) {        if(SSSR_P2 & (1 << 3)) {            while(SSSR_P2 & (1 << 3)) {                (void)SSDR_P2;            }            break;        }        mdelay(1);    }    up(&serial_mutex);    ts->irq = HX4700_IRQ( TOUCHPANEL_IRQ_N );    retval = request_irq(ts->irq, pen_isr, SA_INTERRUPT, "hx4700_ts", ts);    if(retval) {        printk("Unable to get interrupt\n");        input_unregister_device (ts->input);        return -ENODEV;    }    set_irq_type(ts->irq, IRQT_FALLING);    /* *** Initialize the ASIC3 key interrupts *** */    /* Maybe shouldn't do this here, but take advantage of input     * device already configured */    asic3_key[0].gpiod_val = GPIOD_KEY_AP2_N;    asic3_key[0].gpiod_bit = (1<<GPIOD_KEY_AP2_N);    asic3_key[0].rising = 0;    asic3_key[0].key = _KEY_CALENDAR;    irq = asic3_irq_base( &hx4700_asic3.dev ) + ASIC3_GPIOD_IRQ_BASE            + GPIOD_KEY_AP2_N;    err = request_irq( irq, key_isr, SA_INTERRUPT, "HX4700 AP2 Key",        (void *)&asic3_key[0] );    if (err) {        printk(KERN_ERR "GPIOD_KEY_AP2_N: can't request IRQ\n");    } else {        set_irq_type( irq, IRQT_FALLING );        asic3_key[0].irq = irq;    }    asic3_key[1].gpiod_val = GPIOD_KEY_AP4_N;    asic3_key[1].gpiod_bit = (1<<GPIOD_KEY_AP4_N);    asic3_key[1].rising = 0;    asic3_key[1].key = _KEY_HOMEPAGE;    irq = asic3_irq_base( &hx4700_asic3.dev ) + ASIC3_GPIOD_IRQ_BASE            + GPIOD_KEY_AP4_N;    err = request_irq( irq, key_isr, SA_INTERRUPT, "HX4700 AP4 Key",        (void *)&asic3_key[1] );    if (err) {        printk(KERN_ERR "GPIOD_KEY_AP4_N: can't request IRQ\n");    } else {        set_irq_type( irq, IRQT_FALLING );        asic3_key[1].irq = irq;    }    asic3_key[2].gpiod_val = GPIOD_AUD_RECORD_N;    asic3_key[2].gpiod_bit = (1<<GPIOD_AUD_RECORD_N);    asic3_key[2].rising = 0;    asic3_key[2].key = _KEY_RECORD;    irq = asic3_irq_base( &hx4700_asic3.dev ) + ASIC3_GPIOD_IRQ_BASE            + GPIOD_AUD_RECORD_N;    err = request_irq( irq, key_isr, SA_INTERRUPT, "HX4700 Record",        (void *)&asic3_key[2] );    if (err) {        printk(KERN_ERR "GPIOD_AUD_RECORD_N: can't request IRQ\n");    } else {        set_irq_type( irq, IRQT_FALLING );        asic3_key[2].irq = irq;    }    return 0;}static intts_remove (struct device *dev){    int i;    struct touchscreen_data *ts = dev_get_drvdata(dev);    input_unregister_device (ts->input);    del_timer_sync (&ts->timer);    free_irq (ts->irq, ts);    for (i=0; i<3; i++) {        if (asic3_key[i].irq != 0)            free_irq( asic3_key[i].irq, &asic3_key[i] );    }    kfree(ts);    pxa_set_cken(CKEN3_SSP2, 0);    return 0;}static intts_suspend (struct device *dev, pm_message_t state){    disable_irq(HX4700_IRQ(TOUCHPANEL_IRQ_N));    return 0;}static intts_resume (struct device *dev){    struct touchscreen_data *ts = dev_get_drvdata(dev);    ts->state = STATE_WAIT_FOR_TOUCH;    ssp_init();    enable_irq(HX4700_IRQ(TOUCHPANEL_IRQ_N));    return 0;}static struct device_driver ts_driver = {    .name     = "hx4700-ts",    .bus      = &platform_bus_type,    .probe    = ts_probe,    .remove   = ts_remove,    .suspend  = ts_suspend,    .resume   = ts_resume};static int tssim_init(void);static intts_module_init (void){    printk(KERN_NOTICE "hx4700 Touch Screen Driver\n");    if(tssim_init()) {        printk(KERN_NOTICE "  TS Simulator Not Installed\n");    } else {        printk(KERN_NOTICE "  TS Simulator Installed\n");    }    return driver_register(&ts_driver);}static void tssim_exit(void);static voidts_module_cleanup (void){    tssim_exit();    driver_unregister (&ts_driver);}/************* Code for Touch Screen Simulation for FBVNC Server **********/static        dev_t     dev;static struct cdev      *cdev;static long a0 = -1122, a2 = 33588528, a4 = 1452, a5 = -2970720, a6 = 65536;/* The input into the input subsystem is prior to correction from calibration. * So we have to undo the effects of the calibration.  It's actually a * complicated equation where the calibrated value of X depends on the * uncalibrated values of X and Y.  Fortunately, at least on the hx4700, the * multiplier for the Y value is zero, so I assume that here.  It is a shame * that the tslib does not allow multiple inputs.  Then we could do another * driver for this (as it was originally) that give input that does not * require calibration. */static inttssim_ioctl(struct inode *inode, struct file *fp, unsigned int ioctlnum, unsigned long parm){    switch(ioctlnum) {        case 0: a0 = parm; break;        case 1: break;        case 2: a2 = parm; break;        case 3: break;        case 4: a4 = parm; break;        case 5: a5 = parm; break;        case 6:                a6 = parm;                printk(KERN_DEBUG "a0 = %ld, a2 = %ld, a4 = %ld, a5 = %ld, a6 = %ld\n",                    a0, a2, a4, a5, a6);                break;        default: return -ENOTTY;    }    return 0;}static inttssim_open(struct inode *inode, struct file *fp){    /* Nothing to do here */    return 0;}static ssize_ttssim_write(struct file *fp, const char __user *data, size_t bytes, loff_t *offset){    unsigned long pressure;    long y;    long x;    x        = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); data += 4;    y        = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); data += 4;    pressure = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); data += 4;    input_report_abs(ts_data->input, ABS_PRESSURE, pressure?1:0);    input_report_abs(ts_data->input, ABS_X, ((x * a6) - a2)/a0);    input_report_abs(ts_data->input, ABS_Y, ((y * a6) - a5)/a4);    input_sync(ts_data->input);    return bytes;}int tssim_close(struct inode *inode, struct file *fp){    return 0;}struct file_operations fops = {    THIS_MODULE,    .write      = tssim_write,    .open       = tssim_open,    .release    = tssim_close,    .ioctl      = tssim_ioctl,};static int battery_class;static int get_min_voltage(struct battery *b){    return 1000;}static int get_max_voltage(struct battery *b){    return 1400; /* mV */}static int get_max_charge(struct battery *b){    return 100;}static int get_voltage(struct battery *b){    static int battery_sample;    if(!down_interruptible(&serial_mutex)) {        int i;        int ssrval;        while(!(SSSR_P2 & (1 << 2)))            ;        SSDR_P2 = 0xe70000;        while(!(SSSR_P2 & (1 << 2)))            ;        SSDR_P2 = 0xe70000;        while(!(SSSR_P2 & (1 << 2)))            ;        SSDR_P2 = 0xd00000;     /* Dummy command to allow pen interrupts again */        for(i = 0; i < 10; i++) {            ssrval = SSSR_P2;            if(ssrval & (1 << 3)) { /* Look at Rx Not Empty bit */                int number_of_entries_in_fifo;                number_of_entries_in_fifo = ((ssrval >> 12) & 0xf) + 1;                if(number_of_entries_in_fifo == 3) {                    break;                }            }            msleep(1);        }        if(i < 1000) {            (void) SSDR_P2;            battery_sample = SSDR_P2 & 0xfff;            (void) SSDR_P2;        } else {            /* Make sure the FIFO is empty */            while(SSSR_P2 & (1 << 3)) {                (void) SSDR_P2;            }            battery_sample = -1;        }        up(&serial_mutex);    }    return battery_sample;}static int get_charge(struct battery *b){    return 100;}static int get_status(struct battery *b){    return 1;}static struct battery hx4700_power = {    .name               = "hx4700_backup",    .id                 = "backup",    .get_min_voltage    = get_min_voltage,    .get_min_current    = 0,    .get_min_charge     = 0,    .get_max_voltage    = get_max_voltage,    .get_max_current    = 0,    .get_max_charge     = get_max_charge,    .get_temp           = 0,    .get_voltage        = get_voltage,    .get_current        = 0,    .get_charge         = get_charge,    .get_status         = get_status,};static intbattery_class_uevent(struct class_device *dev, char **envp, int num_envp,    char *buffer, int buffer_size){        return 0;}static voidbattery_class_release(struct class_device *dev){}static voidbattery_class_class_release(struct class *class){}static inttssim_init(void){    int retval;    retval = alloc_chrdev_region(&dev, 0, 1, "tssim");    if(retval) {        printk(KERN_ERR "TSSIM Unable to allocate device numbers\n");        return retval;    }    cdev = cdev_alloc();    cdev->owner = THIS_MODULE;    cdev->ops = &fops;    retval = cdev_add(cdev, dev, 1);    if(retval) {        printk(KERN_ERR "Unable to add cdev\n");        unregister_chrdev_region(dev, 1);        return retval;    }    battery_class = 0;    if(battery_class_register(&hx4700_power)) {        printk(KERN_ERR "hx4700_ts: Could not register battery class\n");    } else {        battery_class = 1;        hx4700_power.class_dev.class->uevent        = battery_class_uevent;        hx4700_power.class_dev.class->release       = battery_class_release;        hx4700_power.class_dev.class->class_release = battery_class_class_release;    }    return 0;}static voidtssim_exit(void){    cdev_del(cdev);    unregister_chrdev_region(dev, 1);    if(battery_class)  {        battery_class_unregister(&hx4700_power);    }    return;}module_init(ts_module_init);module_exit(ts_module_cleanup);MODULE_LICENSE("GPL");MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");MODULE_DESCRIPTION("hx4700 Touch Screen Driver");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -