Input: tsc2005 - use true/false for boolean variables
[cascardo/linux.git] / drivers / input / touchscreen / tsc2005.c
index 2435235..f457cb9 100644 (file)
@@ -140,7 +140,8 @@ struct tsc2005 {
 
        bool                    disabled;
        unsigned int            disable_depth;
-       unsigned int            pen_down;
+
+       bool                    pen_down;
 
        void                    (*set_reset)(bool enable);
 };
@@ -197,7 +198,7 @@ static void tsc2005_read(struct tsc2005 *ts, u8 reg, u16 *value)
        struct spi_message msg;
        struct tsc2005_spi_rd spi_rd = { { 0 }, 0, 0 };
 
-       tsc2005_setup_read(&spi_rd, reg, 1);
+       tsc2005_setup_read(&spi_rd, reg, true);
 
        spi_message_init(&msg);
        spi_message_add_tail(&spi_rd.spi_xfer, &msg);
@@ -214,13 +215,13 @@ static void tsc2005_update_pen_state(struct tsc2005 *ts,
                input_report_abs(ts->idev, ABS_PRESSURE, pressure);
                if (!ts->pen_down) {
                        input_report_key(ts->idev, BTN_TOUCH, !!pressure);
-                       ts->pen_down = 1;
+                       ts->pen_down = true;
                }
        } else {
                input_report_abs(ts->idev, ABS_PRESSURE, 0);
                if (ts->pen_down) {
                        input_report_key(ts->idev, BTN_TOUCH, 0);
-                       ts->pen_down = 0;
+                       ts->pen_down = false;
                }
        }
        input_sync(ts->idev);
@@ -411,13 +412,6 @@ static ssize_t tsc2005_selftest_show(struct device *dev,
        u16 temp_high_test;
        unsigned int result;
 
-       if (!ts->set_reset) {
-               dev_warn(&ts->spi->dev,
-                        "unable to selftest: no reset function\n");
-               result = 0;
-               goto out;
-       }
-
        mutex_lock(&ts->mutex);
 
        /*
@@ -436,9 +430,9 @@ static ssize_t tsc2005_selftest_show(struct device *dev,
        }
 
        /* hardware reset */
-       ts->set_reset(0);
+       ts->set_reset(false);
        usleep_range(100, 500); /* only 10us required */
-       ts->set_reset(1);
+       ts->set_reset(true);
        tsc2005_enable(ts);
 
        /* test that the reset really happened */
@@ -451,11 +445,38 @@ static ssize_t tsc2005_selftest_show(struct device *dev,
 
        mutex_unlock(&ts->mutex);
 
-out:
        return sprintf(buf, "%u\n", result);
 }
+
 static DEVICE_ATTR(selftest, S_IRUGO, tsc2005_selftest_show, NULL);
 
+static struct attribute *tsc2005_attrs[] = {
+       &dev_attr_disable.attr,
+       &dev_attr_selftest.attr,
+       NULL
+};
+
+static mode_t tsc2005_attr_is_visible(struct kobject *kobj,
+                                     struct attribute *attr, int n)
+{
+       struct device *dev = container_of(kobj, struct device, kobj);
+       struct spi_device *spi = to_spi_device(dev);
+       struct tsc2005 *ts = spi_get_drvdata(spi);
+       mode_t mode = attr->mode;
+
+       if (attr == &dev_attr_selftest.attr) {
+               if (!ts->set_reset)
+                       mode = 0;
+       }
+
+       return mode;
+}
+
+static const struct attribute_group tsc2005_attr_group = {
+       .is_visible     = tsc2005_attr_is_visible,
+       .attrs          = tsc2005_attrs,
+};
+
 static void tsc2005_esd_timer(unsigned long data)
 {
        struct tsc2005 *ts = (struct tsc2005 *)data;
@@ -480,10 +501,10 @@ static void tsc2005_esd_work(struct work_struct *work)
        tsc2005_read(ts, TSC2005_REG_CFR0, &r);
        if ((r ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK) {
                dev_info(&ts->spi->dev, "TSC2005 not responding - resetting\n");
-               ts->set_reset(0);
+               ts->set_reset(false);
                tsc2005_update_pen_state(ts, 0, 0, 0);
                usleep_range(100, 500); /* only 10us required */
-               ts->set_reset(1);
+               ts->set_reset(true);
                tsc2005_start_scan(ts);
        }
 
@@ -497,10 +518,10 @@ out:
 
 static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts)
 {
-       tsc2005_setup_read(&ts->spi_x, TSC2005_REG_X, 0);
-       tsc2005_setup_read(&ts->spi_y, TSC2005_REG_Y, 0);
-       tsc2005_setup_read(&ts->spi_z1, TSC2005_REG_Z1, 0);
-       tsc2005_setup_read(&ts->spi_z2, TSC2005_REG_Z2, 1);
+       tsc2005_setup_read(&ts->spi_x, TSC2005_REG_X, false);
+       tsc2005_setup_read(&ts->spi_y, TSC2005_REG_Y, false);
+       tsc2005_setup_read(&ts->spi_z1, TSC2005_REG_Z1, false);
+       tsc2005_setup_read(&ts->spi_z2, TSC2005_REG_Z2, true);
 
        spi_message_init(&ts->spi_read_msg);
        spi_message_add_tail(&ts->spi_x.spi_xfer, &ts->spi_read_msg);
@@ -509,140 +530,130 @@ static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts)
        spi_message_add_tail(&ts->spi_z2.spi_xfer, &ts->spi_read_msg);
 }
 
-static struct attribute *tsc2005_attrs[] = {
-       &dev_attr_disable.attr,
-       &dev_attr_selftest.attr,
-       NULL
-};
-
-static struct attribute_group tsc2005_attr_group = {
-       .attrs = tsc2005_attrs,
-};
-
-static int __devinit tsc2005_setup(struct tsc2005 *ts,
-                                  struct tsc2005_platform_data *pdata)
+static int __devinit tsc2005_probe(struct spi_device *spi)
 {
-       int r;
-       int fudge_x;
-       int fudge_y;
-       int fudge_p;
-       int p_max;
-       int x_max;
-       int y_max;
+       const struct tsc2005_platform_data *pdata = spi->dev.platform_data;
+       struct tsc2005 *ts;
+       struct input_dev *input_dev;
+       unsigned int max_x, max_y, max_p;
+       unsigned int fudge_x, fudge_y, fudge_p;
+       int error;
 
-       mutex_init(&ts->mutex);
+       if (!pdata) {
+               dev_dbg(&spi->dev, "no platform data\n");
+               return -ENODEV;
+       }
 
-       tsc2005_setup_spi_xfer(ts);
+       fudge_x = pdata->ts_x_fudge        ? : 4;
+       fudge_y = pdata->ts_y_fudge        ? : 8;
+       fudge_p = pdata->ts_pressure_fudge ? : 2;
+       max_x   = pdata->ts_x_max          ? : MAX_12BIT;
+       max_y   = pdata->ts_y_max          ? : MAX_12BIT;
+       max_p   = pdata->ts_pressure_max   ? : MAX_12BIT;
 
-       init_timer(&ts->penup_timer);
-       setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts);
-       INIT_WORK(&ts->penup_work, tsc2005_penup_work);
+       if (spi->irq <= 0) {
+               dev_dbg(&spi->dev, "no irq\n");
+               return -ENODEV;
+       }
 
-       fudge_x         = pdata->ts_x_fudge        ? : 4;
-       fudge_y         = pdata->ts_y_fudge        ? : 8;
-       fudge_p         = pdata->ts_pressure_fudge ? : 2;
-       x_max           = pdata->ts_x_max          ? : MAX_12BIT;
-       y_max           = pdata->ts_y_max          ? : MAX_12BIT;
-       p_max           = pdata->ts_pressure_max   ? : MAX_12BIT;
-       ts->x_plate_ohm = pdata->ts_x_plate_ohm    ? : 280;
-       ts->esd_timeout = pdata->esd_timeout_ms;
-       ts->set_reset   = pdata->set_reset;
+       spi->mode = SPI_MODE_0;
+       spi->bits_per_word = 8;
+       if (!spi->max_speed_hz)
+               spi->max_speed_hz = TSC2005_SPI_MAX_SPEED_HZ;
 
-       ts->idev = input_allocate_device();
-       if (ts->idev == NULL)
-               return -ENOMEM;
-       ts->idev->name = "TSC2005 touchscreen";
-       snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts",
-                dev_name(&ts->spi->dev));
-       ts->idev->phys = ts->phys;
-       ts->idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
-       ts->idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-       ts->idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
-       input_set_abs_params(ts->idev, ABS_X, 0, x_max, fudge_x, 0);
-       input_set_abs_params(ts->idev, ABS_Y, 0, y_max, fudge_y, 0);
-       input_set_abs_params(ts->idev, ABS_PRESSURE, 0, p_max, fudge_p, 0);
-
-       r = request_threaded_irq(ts->spi->irq, tsc2005_irq_handler,
-                                tsc2005_irq_thread, IRQF_TRIGGER_RISING,
-                                "tsc2005", ts);
-       if (r) {
-               dev_err(&ts->spi->dev, "request_threaded_irq(): %d\n", r);
-               goto err1;
-       }
-       set_irq_wake(ts->spi->irq, 1);
+       error = spi_setup(spi);
+       if (error)
+               return error;
 
-       r = input_register_device(ts->idev);
-       if (r) {
-               dev_err(&ts->spi->dev, "input_register_device(): %d\n", r);
-               goto err2;
+       ts = kzalloc(sizeof(*ts), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!ts || !input_dev) {
+               error = -ENOMEM;
+               goto err_free_mem;
        }
 
-       r = sysfs_create_group(&ts->spi->dev.kobj, &tsc2005_attr_group);
-       if (r)
-               dev_warn(&ts->spi->dev, "sysfs entry creation failed: %d\n", r);
+       ts->spi = spi;
+       ts->idev = input_dev;
 
-       tsc2005_start_scan(ts);
+       ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280;
+       ts->esd_timeout = pdata->esd_timeout_ms;
+       ts->set_reset   = pdata->set_reset;
 
-       if (!ts->esd_timeout || !ts->set_reset)
-               goto done;
+       mutex_init(&ts->mutex);
+
+       setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts);
+       INIT_WORK(&ts->penup_work, tsc2005_penup_work);
 
-       /* start the optional ESD watchdog */
        setup_timer(&ts->esd_timer, tsc2005_esd_timer, (unsigned long)ts);
        INIT_WORK(&ts->esd_work, tsc2005_esd_work);
-       mod_timer(&ts->esd_timer,
-                 round_jiffies(jiffies + msecs_to_jiffies(ts->esd_timeout)));
 
-done:
-       return 0;
-
-err2:
-       free_irq(ts->spi->irq, ts);
-
-err1:
-       input_free_device(ts->idev);
-       return r;
-}
+       tsc2005_setup_spi_xfer(ts);
 
-static int __devinit tsc2005_probe(struct spi_device *spi)
-{
-       struct tsc2005_platform_data *pdata = spi->dev.platform_data;
-       struct tsc2005 *ts;
-       int r;
+       snprintf(ts->phys, sizeof(ts->phys),
+                "%s/input-ts", dev_name(&spi->dev));
+
+       input_dev->name = "TSC2005 touchscreen";
+       input_dev->phys = ts->phys;
+       input_dev->id.bustype = BUS_SPI;
+       input_dev->dev.parent = &spi->dev;
+       input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+       input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);
+       input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
+       input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
+
+       error = request_threaded_irq(spi->irq,
+                                    tsc2005_irq_handler, tsc2005_irq_thread,
+                                    IRQF_TRIGGER_RISING, "tsc2005", ts);
+       if (error) {
+               dev_err(&spi->dev, "Failed to request irq, err: %d\n", error);
+               goto err_free_mem;
+       }
 
-       if (spi->irq < 0) {
-               dev_dbg(&spi->dev, "no irq\n");
-               return -ENODEV;
+       spi_set_drvdata(spi, ts);
+       error = sysfs_create_group(&spi->dev.kobj, &tsc2005_attr_group);
+       if (error) {
+               dev_err(&spi->dev,
+                       "Failed to create sysfs attributes, err: %d\n", error);
+               goto err_clear_drvdata;
        }
 
-       if (!pdata) {
-               dev_dbg(&spi->dev, "no platform data\n");
-               return -ENODEV;
+       error = input_register_device(ts->idev);
+       if (error) {
+               dev_err(&spi->dev,
+                       "Failed to register input device, err: %d\n", error);
+               goto err_remove_sysfs;
        }
 
-       ts = kzalloc(sizeof(*ts), GFP_KERNEL);
-       if (ts == NULL)
-               return -ENOMEM;
+       tsc2005_start_scan(ts);
 
-       spi_set_drvdata(spi, ts);
-       ts->spi = spi;
-       spi->dev.power.power_state = PMSG_ON;
-       spi->mode = SPI_MODE_0;
-       spi->bits_per_word = 8;
-       if (!spi->max_speed_hz)
-               spi->max_speed_hz = TSC2005_SPI_MAX_SPEED_HZ;
-       spi_setup(spi);
+       if (ts->esd_timeout && ts->set_reset) {
+               /* start the optional ESD watchdog */
+               mod_timer(&ts->esd_timer, round_jiffies(jiffies +
+                                       msecs_to_jiffies(ts->esd_timeout)));
+       }
 
-       r = tsc2005_setup(ts, pdata);
-       if (r)
-               kfree(ts);
-       return r;
+       set_irq_wake(spi->irq, 1);
+       return 0;
+
+err_remove_sysfs:
+       sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group);
+err_clear_drvdata:
+       spi_set_drvdata(spi, NULL);
+       free_irq(spi->irq, ts);
+err_free_mem:
+       input_free_device(input_dev);
+       kfree(ts);
+       return error;
 }
 
 static int __devexit tsc2005_remove(struct spi_device *spi)
 {
        struct tsc2005 *ts = spi_get_drvdata(spi);
 
+       sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group);
+
        mutex_lock(&ts->mutex);
        tsc2005_disable(ts);
        mutex_unlock(&ts->mutex);
@@ -654,11 +665,11 @@ static int __devexit tsc2005_remove(struct spi_device *spi)
        flush_work(&ts->esd_work);
        flush_work(&ts->penup_work);
 
-       sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group);
        free_irq(ts->spi->irq, ts);
        input_unregister_device(ts->idev);
        kfree(ts);
 
+       spi_set_drvdata(spi, NULL);
        return 0;
 }
 
@@ -713,4 +724,5 @@ static void __exit tsc2005_exit(void)
 module_exit(tsc2005_exit);
 
 MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>");
+MODULE_DESCRIPTION("TSC2005 Touchscreen Driver");
 MODULE_LICENSE("GPL");