static void ad7879_setup(struct ad7879 *ts) { ts->cmd_crtl3 = AD7879_YPLUS_BIT | AD7879_XPLUS_BIT | AD7879_Z2_BIT | AD7879_Z1_BIT | AD7879_TEMPMASK_BIT | AD7879_AUXVBATMASK_BIT | AD7879_GPIOALERTMASK_BIT; ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | AD7879_AVG(ts->averaging) | AD7879_MFS(ts->median) | AD7879_FCD(ts->first_conversion_delay) | ts->gpio_init; ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | AD7879_ACQ(ts->acquisition_time) | AD7879_TMR(ts->pen_down_acc_interval); ad7879_write(ts->bus, AD7879_REG_CTRL2, ts->cmd_crtl2); ad7879_write(ts->bus, AD7879_REG_CTRL3, ts->cmd_crtl3); ad7879_write(ts->bus, AD7879_REG_CTRL1, ts->cmd_crtl1); }
struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq, const struct ad7879_bus_ops *bops) { struct ad7879_platform_data *pdata = dev->platform_data; struct ad7879 *ts; struct input_dev *input_dev; int err; u16 revid; if (!irq) { dev_err(dev, "no IRQ?\n"); err = -EINVAL; goto err_out; } if (!pdata) { dev_err(dev, "no platform data?\n"); err = -EINVAL; goto err_out; } ts = kzalloc(sizeof(*ts), GFP_KERNEL); input_dev = input_allocate_device(); if (!ts || !input_dev) { err = -ENOMEM; goto err_free_mem; } ts->bops = bops; ts->dev = dev; ts->input = input_dev; ts->irq = irq; setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; ts->pressure_max = pdata->pressure_max ? : ~0; ts->first_conversion_delay = pdata->first_conversion_delay; ts->acquisition_time = pdata->acquisition_time; ts->averaging = pdata->averaging; ts->pen_down_acc_interval = pdata->pen_down_acc_interval; ts->median = pdata->median; snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); input_dev->name = "AD7879 Touchscreen"; input_dev->phys = ts->phys; input_dev->dev.parent = dev; input_dev->id.bustype = bops->bustype; input_dev->open = ad7879_open; input_dev->close = ad7879_close; input_set_drvdata(input_dev, ts); __set_bit(EV_ABS, input_dev->evbit); __set_bit(ABS_X, input_dev->absbit); __set_bit(ABS_Y, input_dev->absbit); __set_bit(ABS_PRESSURE, input_dev->absbit); __set_bit(EV_KEY, input_dev->evbit); __set_bit(BTN_TOUCH, input_dev->keybit); input_set_abs_params(input_dev, ABS_X, pdata->x_min ? : 0, pdata->x_max ? : MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_Y, pdata->y_min ? : 0, pdata->y_max ? : MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_PRESSURE, pdata->pressure_min, pdata->pressure_max, 0, 0); err = ad7879_write(ts, AD7879_REG_CTRL2, AD7879_RESET); if (err < 0) { dev_err(dev, "Failed to write %s\n", input_dev->name); goto err_free_mem; } revid = ad7879_read(ts, AD7879_REG_REVID); input_dev->id.product = (revid & 0xff); input_dev->id.version = revid >> 8; if (input_dev->id.product != devid) { dev_err(dev, "Failed to probe %s (%x vs %x)\n", input_dev->name, devid, revid); err = -ENODEV; goto err_free_mem; } ts->cmd_crtl3 = AD7879_YPLUS_BIT | AD7879_XPLUS_BIT | AD7879_Z2_BIT | AD7879_Z1_BIT | AD7879_TEMPMASK_BIT | AD7879_AUXVBATMASK_BIT | AD7879_GPIOALERTMASK_BIT; ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | AD7879_AVG(ts->averaging) | AD7879_MFS(ts->median) | AD7879_FCD(ts->first_conversion_delay); ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | AD7879_ACQ(ts->acquisition_time) | AD7879_TMR(ts->pen_down_acc_interval); err = request_threaded_irq(ts->irq, NULL, ad7879_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), ts); if (err) { dev_err(dev, "irq %d busy?\n", ts->irq); goto err_free_mem; } __ad7879_disable(ts); err = sysfs_create_group(&dev->kobj, &ad7879_attr_group); if (err) goto err_free_irq; err = ad7879_gpio_add(ts, pdata); if (err) goto err_remove_attr; err = input_register_device(input_dev); if (err) goto err_remove_gpio; return ts; err_remove_gpio: ad7879_gpio_remove(ts); err_remove_attr: sysfs_remove_group(&dev->kobj, &ad7879_attr_group); err_free_irq: free_irq(ts->irq, ts); err_free_mem: input_free_device(input_dev); kfree(ts); err_out: return ERR_PTR(err); }
static int __devinit ad7879_construct(bus_device *bus, struct ad7879 *ts) { struct input_dev *input_dev; struct ad7879_platform_data *pdata = bus->dev.platform_data; int err; u16 revid; if (!bus->irq) { dev_err(&bus->dev, "no IRQ?\n"); return -ENODEV; } if (!pdata) { dev_err(&bus->dev, "no platform data?\n"); return -ENODEV; } input_dev = input_allocate_device(); if (!input_dev) return -ENOMEM; ts->input = input_dev; setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts); INIT_WORK(&ts->work, ad7879_work); mutex_init(&ts->mutex); ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; ts->pressure_max = pdata->pressure_max ? : ~0; ts->first_conversion_delay = pdata->first_conversion_delay; ts->acquisition_time = pdata->acquisition_time; ts->averaging = pdata->averaging; ts->pen_down_acc_interval = pdata->pen_down_acc_interval; ts->median = pdata->median; snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&bus->dev)); input_dev->name = "AD7879 Touchscreen"; input_dev->phys = ts->phys; input_dev->dev.parent = &bus->dev; __set_bit(EV_ABS, input_dev->evbit); __set_bit(ABS_X, input_dev->absbit); __set_bit(ABS_Y, input_dev->absbit); __set_bit(ABS_PRESSURE, input_dev->absbit); input_set_abs_params(input_dev, ABS_X, pdata->x_min ? : 0, pdata->x_max ? : MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_Y, pdata->y_min ? : 0, pdata->y_max ? : MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_PRESSURE, pdata->pressure_min, pdata->pressure_max, 0, 0); err = ad7879_write(bus, AD7879_REG_CTRL2, AD7879_RESET); if (err < 0) { dev_err(&bus->dev, "Failed to write %s\n", input_dev->name); goto err_free_mem; } revid = ad7879_read(bus, AD7879_REG_REVID); if ((revid & 0xFF) != AD7879_DEVID) { dev_err(&bus->dev, "Failed to probe %s\n", input_dev->name); err = -ENODEV; goto err_free_mem; } ts->cmd_crtl3 = AD7879_YPLUS_BIT | AD7879_XPLUS_BIT | AD7879_Z2_BIT | AD7879_Z1_BIT | AD7879_TEMPMASK_BIT | AD7879_AUXVBATMASK_BIT | AD7879_GPIOALERTMASK_BIT; ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR | AD7879_AVG(ts->averaging) | AD7879_MFS(ts->median) | AD7879_FCD(ts->first_conversion_delay); ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 | AD7879_ACQ(ts->acquisition_time) | AD7879_TMR(ts->pen_down_acc_interval); ad7879_setup(ts); err = request_irq(bus->irq, ad7879_irq, IRQF_TRIGGER_FALLING, bus->dev.driver->name, ts); if (err) { dev_err(&bus->dev, "irq %d busy?\n", bus->irq); goto err_free_mem; } err = sysfs_create_group(&bus->dev.kobj, &ad7879_attr_group); if (err) goto err_free_irq; err = ad7879_gpio_add(&bus->dev); if (err) goto err_remove_attr; err = input_register_device(input_dev); if (err) goto err_remove_gpio; dev_info(&bus->dev, "Rev.%d touchscreen, irq %d\n", revid >> 8, bus->irq); return 0; err_remove_gpio: ad7879_gpio_remove(&bus->dev); err_remove_attr: sysfs_remove_group(&bus->dev.kobj, &ad7879_attr_group); err_free_irq: free_irq(bus->irq, ts); err_free_mem: input_free_device(input_dev); return err; }