Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com>
0004  * Sponsored by ARMadeus Systems
0005  *
0006  * Driver for Austria Microsystems joysticks AS5011
0007  *
0008  * TODO:
0009  *  - Power on the chip when open() and power down when close()
0010  *  - Manage power mode
0011  */
0012 
0013 #include <linux/i2c.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/input.h>
0016 #include <linux/gpio.h>
0017 #include <linux/delay.h>
0018 #include <linux/input/as5011.h>
0019 #include <linux/slab.h>
0020 #include <linux/module.h>
0021 
0022 #define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick"
0023 #define MODULE_DEVICE_ALIAS "as5011"
0024 
0025 MODULE_AUTHOR("Fabien Marteau <fabien.marteau@armadeus.com>");
0026 MODULE_DESCRIPTION(DRIVER_DESC);
0027 MODULE_LICENSE("GPL");
0028 
0029 /* registers */
0030 #define AS5011_CTRL1        0x76
0031 #define AS5011_CTRL2        0x75
0032 #define AS5011_XP       0x43
0033 #define AS5011_XN       0x44
0034 #define AS5011_YP       0x53
0035 #define AS5011_YN       0x54
0036 #define AS5011_X_REG        0x41
0037 #define AS5011_Y_REG        0x42
0038 #define AS5011_X_RES_INT    0x51
0039 #define AS5011_Y_RES_INT    0x52
0040 
0041 /* CTRL1 bits */
0042 #define AS5011_CTRL1_LP_PULSED      0x80
0043 #define AS5011_CTRL1_LP_ACTIVE      0x40
0044 #define AS5011_CTRL1_LP_CONTINUE    0x20
0045 #define AS5011_CTRL1_INT_WUP_EN     0x10
0046 #define AS5011_CTRL1_INT_ACT_EN     0x08
0047 #define AS5011_CTRL1_EXT_CLK_EN     0x04
0048 #define AS5011_CTRL1_SOFT_RST       0x02
0049 #define AS5011_CTRL1_DATA_VALID     0x01
0050 
0051 /* CTRL2 bits */
0052 #define AS5011_CTRL2_EXT_SAMPLE_EN  0x08
0053 #define AS5011_CTRL2_RC_BIAS_ON     0x04
0054 #define AS5011_CTRL2_INV_SPINNING   0x02
0055 
0056 #define AS5011_MAX_AXIS 80
0057 #define AS5011_MIN_AXIS (-80)
0058 #define AS5011_FUZZ 8
0059 #define AS5011_FLAT 40
0060 
0061 struct as5011_device {
0062     struct input_dev *input_dev;
0063     struct i2c_client *i2c_client;
0064     unsigned int button_gpio;
0065     unsigned int button_irq;
0066     unsigned int axis_irq;
0067 };
0068 
0069 static int as5011_i2c_write(struct i2c_client *client,
0070                 uint8_t aregaddr,
0071                 uint8_t avalue)
0072 {
0073     uint8_t data[2] = { aregaddr, avalue };
0074     struct i2c_msg msg = {
0075         .addr = client->addr,
0076         .flags = I2C_M_IGNORE_NAK,
0077         .len = 2,
0078         .buf = (uint8_t *)data
0079     };
0080     int error;
0081 
0082     error = i2c_transfer(client->adapter, &msg, 1);
0083     return error < 0 ? error : 0;
0084 }
0085 
0086 static int as5011_i2c_read(struct i2c_client *client,
0087                uint8_t aregaddr, signed char *value)
0088 {
0089     uint8_t data[2] = { aregaddr };
0090     struct i2c_msg msg_set[2] = {
0091         {
0092             .addr = client->addr,
0093             .flags = I2C_M_REV_DIR_ADDR,
0094             .len = 1,
0095             .buf = (uint8_t *)data
0096         },
0097         {
0098             .addr = client->addr,
0099             .flags = I2C_M_RD | I2C_M_NOSTART,
0100             .len = 1,
0101             .buf = (uint8_t *)data
0102         }
0103     };
0104     int error;
0105 
0106     error = i2c_transfer(client->adapter, msg_set, 2);
0107     if (error < 0)
0108         return error;
0109 
0110     *value = data[0] & 0x80 ? -1 * (1 + ~data[0]) : data[0];
0111     return 0;
0112 }
0113 
0114 static irqreturn_t as5011_button_interrupt(int irq, void *dev_id)
0115 {
0116     struct as5011_device *as5011 = dev_id;
0117     int val = gpio_get_value_cansleep(as5011->button_gpio);
0118 
0119     input_report_key(as5011->input_dev, BTN_JOYSTICK, !val);
0120     input_sync(as5011->input_dev);
0121 
0122     return IRQ_HANDLED;
0123 }
0124 
0125 static irqreturn_t as5011_axis_interrupt(int irq, void *dev_id)
0126 {
0127     struct as5011_device *as5011 = dev_id;
0128     int error;
0129     signed char x, y;
0130 
0131     error = as5011_i2c_read(as5011->i2c_client, AS5011_X_RES_INT, &x);
0132     if (error < 0)
0133         goto out;
0134 
0135     error = as5011_i2c_read(as5011->i2c_client, AS5011_Y_RES_INT, &y);
0136     if (error < 0)
0137         goto out;
0138 
0139     input_report_abs(as5011->input_dev, ABS_X, x);
0140     input_report_abs(as5011->input_dev, ABS_Y, y);
0141     input_sync(as5011->input_dev);
0142 
0143 out:
0144     return IRQ_HANDLED;
0145 }
0146 
0147 static int as5011_configure_chip(struct as5011_device *as5011,
0148                 const struct as5011_platform_data *plat_dat)
0149 {
0150     struct i2c_client *client = as5011->i2c_client;
0151     int error;
0152     signed char value;
0153 
0154     /* chip soft reset */
0155     error = as5011_i2c_write(client, AS5011_CTRL1,
0156                  AS5011_CTRL1_SOFT_RST);
0157     if (error < 0) {
0158         dev_err(&client->dev, "Soft reset failed\n");
0159         return error;
0160     }
0161 
0162     mdelay(10);
0163 
0164     error = as5011_i2c_write(client, AS5011_CTRL1,
0165                  AS5011_CTRL1_LP_PULSED |
0166                  AS5011_CTRL1_LP_ACTIVE |
0167                  AS5011_CTRL1_INT_ACT_EN);
0168     if (error < 0) {
0169         dev_err(&client->dev, "Power config failed\n");
0170         return error;
0171     }
0172 
0173     error = as5011_i2c_write(client, AS5011_CTRL2,
0174                  AS5011_CTRL2_INV_SPINNING);
0175     if (error < 0) {
0176         dev_err(&client->dev, "Can't invert spinning\n");
0177         return error;
0178     }
0179 
0180     /* write threshold */
0181     error = as5011_i2c_write(client, AS5011_XP, plat_dat->xp);
0182     if (error < 0) {
0183         dev_err(&client->dev, "Can't write threshold\n");
0184         return error;
0185     }
0186 
0187     error = as5011_i2c_write(client, AS5011_XN, plat_dat->xn);
0188     if (error < 0) {
0189         dev_err(&client->dev, "Can't write threshold\n");
0190         return error;
0191     }
0192 
0193     error = as5011_i2c_write(client, AS5011_YP, plat_dat->yp);
0194     if (error < 0) {
0195         dev_err(&client->dev, "Can't write threshold\n");
0196         return error;
0197     }
0198 
0199     error = as5011_i2c_write(client, AS5011_YN, plat_dat->yn);
0200     if (error < 0) {
0201         dev_err(&client->dev, "Can't write threshold\n");
0202         return error;
0203     }
0204 
0205     /* to free irq gpio in chip */
0206     error = as5011_i2c_read(client, AS5011_X_RES_INT, &value);
0207     if (error < 0) {
0208         dev_err(&client->dev, "Can't read i2c X resolution value\n");
0209         return error;
0210     }
0211 
0212     return 0;
0213 }
0214 
0215 static int as5011_probe(struct i2c_client *client,
0216              const struct i2c_device_id *id)
0217 {
0218     const struct as5011_platform_data *plat_data;
0219     struct as5011_device *as5011;
0220     struct input_dev *input_dev;
0221     int irq;
0222     int error;
0223 
0224     plat_data = dev_get_platdata(&client->dev);
0225     if (!plat_data)
0226         return -EINVAL;
0227 
0228     if (!plat_data->axis_irq) {
0229         dev_err(&client->dev, "No axis IRQ?\n");
0230         return -EINVAL;
0231     }
0232 
0233     if (!i2c_check_functionality(client->adapter,
0234                      I2C_FUNC_NOSTART |
0235                      I2C_FUNC_PROTOCOL_MANGLING)) {
0236         dev_err(&client->dev,
0237             "need i2c bus that supports protocol mangling\n");
0238         return -ENODEV;
0239     }
0240 
0241     as5011 = kmalloc(sizeof(struct as5011_device), GFP_KERNEL);
0242     input_dev = input_allocate_device();
0243     if (!as5011 || !input_dev) {
0244         dev_err(&client->dev,
0245             "Can't allocate memory for device structure\n");
0246         error = -ENOMEM;
0247         goto err_free_mem;
0248     }
0249 
0250     as5011->i2c_client = client;
0251     as5011->input_dev = input_dev;
0252     as5011->button_gpio = plat_data->button_gpio;
0253     as5011->axis_irq = plat_data->axis_irq;
0254 
0255     input_dev->name = "Austria Microsystem as5011 joystick";
0256     input_dev->id.bustype = BUS_I2C;
0257     input_dev->dev.parent = &client->dev;
0258 
0259     input_set_capability(input_dev, EV_KEY, BTN_JOYSTICK);
0260 
0261     input_set_abs_params(input_dev, ABS_X,
0262         AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
0263     input_set_abs_params(as5011->input_dev, ABS_Y,
0264         AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
0265 
0266     error = gpio_request(as5011->button_gpio, "AS5011 button");
0267     if (error < 0) {
0268         dev_err(&client->dev, "Failed to request button gpio\n");
0269         goto err_free_mem;
0270     }
0271 
0272     irq = gpio_to_irq(as5011->button_gpio);
0273     if (irq < 0) {
0274         dev_err(&client->dev,
0275             "Failed to get irq number for button gpio\n");
0276         error = irq;
0277         goto err_free_button_gpio;
0278     }
0279 
0280     as5011->button_irq = irq;
0281 
0282     error = request_threaded_irq(as5011->button_irq,
0283                      NULL, as5011_button_interrupt,
0284                      IRQF_TRIGGER_RISING |
0285                     IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
0286                      "as5011_button", as5011);
0287     if (error < 0) {
0288         dev_err(&client->dev,
0289             "Can't allocate button irq %d\n", as5011->button_irq);
0290         goto err_free_button_gpio;
0291     }
0292 
0293     error = as5011_configure_chip(as5011, plat_data);
0294     if (error)
0295         goto err_free_button_irq;
0296 
0297     error = request_threaded_irq(as5011->axis_irq, NULL,
0298                      as5011_axis_interrupt,
0299                      plat_data->axis_irqflags | IRQF_ONESHOT,
0300                      "as5011_joystick", as5011);
0301     if (error) {
0302         dev_err(&client->dev,
0303             "Can't allocate axis irq %d\n", plat_data->axis_irq);
0304         goto err_free_button_irq;
0305     }
0306 
0307     error = input_register_device(as5011->input_dev);
0308     if (error) {
0309         dev_err(&client->dev, "Failed to register input device\n");
0310         goto err_free_axis_irq;
0311     }
0312 
0313     i2c_set_clientdata(client, as5011);
0314 
0315     return 0;
0316 
0317 err_free_axis_irq:
0318     free_irq(as5011->axis_irq, as5011);
0319 err_free_button_irq:
0320     free_irq(as5011->button_irq, as5011);
0321 err_free_button_gpio:
0322     gpio_free(as5011->button_gpio);
0323 err_free_mem:
0324     input_free_device(input_dev);
0325     kfree(as5011);
0326 
0327     return error;
0328 }
0329 
0330 static int as5011_remove(struct i2c_client *client)
0331 {
0332     struct as5011_device *as5011 = i2c_get_clientdata(client);
0333 
0334     free_irq(as5011->axis_irq, as5011);
0335     free_irq(as5011->button_irq, as5011);
0336     gpio_free(as5011->button_gpio);
0337 
0338     input_unregister_device(as5011->input_dev);
0339     kfree(as5011);
0340 
0341     return 0;
0342 }
0343 
0344 static const struct i2c_device_id as5011_id[] = {
0345     { MODULE_DEVICE_ALIAS, 0 },
0346     { }
0347 };
0348 MODULE_DEVICE_TABLE(i2c, as5011_id);
0349 
0350 static struct i2c_driver as5011_driver = {
0351     .driver = {
0352         .name = "as5011",
0353     },
0354     .probe      = as5011_probe,
0355     .remove     = as5011_remove,
0356     .id_table   = as5011_id,
0357 };
0358 
0359 module_i2c_driver(as5011_driver);