linux/drivers/misc/fsa9480.c
<<
>>
Prefs
   1/*
   2 * fsa9480.c - FSA9480 micro USB switch device driver
   3 *
   4 * Copyright (C) 2010 Samsung Electronics
   5 * Minkyu Kang <mk7.kang@samsung.com>
   6 * Wonguk Jeong <wonguk.jeong@samsung.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/err.h>
  16#include <linux/i2c.h>
  17#include <linux/platform_data/fsa9480.h>
  18#include <linux/irq.h>
  19#include <linux/interrupt.h>
  20#include <linux/workqueue.h>
  21#include <linux/platform_device.h>
  22#include <linux/slab.h>
  23#include <linux/pm_runtime.h>
  24
  25/* FSA9480 I2C registers */
  26#define FSA9480_REG_DEVID               0x01
  27#define FSA9480_REG_CTRL                0x02
  28#define FSA9480_REG_INT1                0x03
  29#define FSA9480_REG_INT2                0x04
  30#define FSA9480_REG_INT1_MASK           0x05
  31#define FSA9480_REG_INT2_MASK           0x06
  32#define FSA9480_REG_ADC                 0x07
  33#define FSA9480_REG_TIMING1             0x08
  34#define FSA9480_REG_TIMING2             0x09
  35#define FSA9480_REG_DEV_T1              0x0a
  36#define FSA9480_REG_DEV_T2              0x0b
  37#define FSA9480_REG_BTN1                0x0c
  38#define FSA9480_REG_BTN2                0x0d
  39#define FSA9480_REG_CK                  0x0e
  40#define FSA9480_REG_CK_INT1             0x0f
  41#define FSA9480_REG_CK_INT2             0x10
  42#define FSA9480_REG_CK_INTMASK1         0x11
  43#define FSA9480_REG_CK_INTMASK2         0x12
  44#define FSA9480_REG_MANSW1              0x13
  45#define FSA9480_REG_MANSW2              0x14
  46
  47/* Control */
  48#define CON_SWITCH_OPEN         (1 << 4)
  49#define CON_RAW_DATA            (1 << 3)
  50#define CON_MANUAL_SW           (1 << 2)
  51#define CON_WAIT                (1 << 1)
  52#define CON_INT_MASK            (1 << 0)
  53#define CON_MASK                (CON_SWITCH_OPEN | CON_RAW_DATA | \
  54                                CON_MANUAL_SW | CON_WAIT)
  55
  56/* Device Type 1 */
  57#define DEV_USB_OTG             (1 << 7)
  58#define DEV_DEDICATED_CHG       (1 << 6)
  59#define DEV_USB_CHG             (1 << 5)
  60#define DEV_CAR_KIT             (1 << 4)
  61#define DEV_UART                (1 << 3)
  62#define DEV_USB                 (1 << 2)
  63#define DEV_AUDIO_2             (1 << 1)
  64#define DEV_AUDIO_1             (1 << 0)
  65
  66#define DEV_T1_USB_MASK         (DEV_USB_OTG | DEV_USB)
  67#define DEV_T1_UART_MASK        (DEV_UART)
  68#define DEV_T1_CHARGER_MASK     (DEV_DEDICATED_CHG | DEV_USB_CHG)
  69
  70/* Device Type 2 */
  71#define DEV_AV                  (1 << 6)
  72#define DEV_TTY                 (1 << 5)
  73#define DEV_PPD                 (1 << 4)
  74#define DEV_JIG_UART_OFF        (1 << 3)
  75#define DEV_JIG_UART_ON         (1 << 2)
  76#define DEV_JIG_USB_OFF         (1 << 1)
  77#define DEV_JIG_USB_ON          (1 << 0)
  78
  79#define DEV_T2_USB_MASK         (DEV_JIG_USB_OFF | DEV_JIG_USB_ON)
  80#define DEV_T2_UART_MASK        (DEV_JIG_UART_OFF | DEV_JIG_UART_ON)
  81#define DEV_T2_JIG_MASK         (DEV_JIG_USB_OFF | DEV_JIG_USB_ON | \
  82                                DEV_JIG_UART_OFF | DEV_JIG_UART_ON)
  83
  84/*
  85 * Manual Switch
  86 * D- [7:5] / D+ [4:2]
  87 * 000: Open all / 001: USB / 010: AUDIO / 011: UART / 100: V_AUDIO
  88 */
  89#define SW_VAUDIO               ((4 << 5) | (4 << 2))
  90#define SW_UART                 ((3 << 5) | (3 << 2))
  91#define SW_AUDIO                ((2 << 5) | (2 << 2))
  92#define SW_DHOST                ((1 << 5) | (1 << 2))
  93#define SW_AUTO                 ((0 << 5) | (0 << 2))
  94
  95/* Interrupt 1 */
  96#define INT_DETACH              (1 << 1)
  97#define INT_ATTACH              (1 << 0)
  98
  99struct fsa9480_usbsw {
 100        struct i2c_client               *client;
 101        struct fsa9480_platform_data    *pdata;
 102        int                             dev1;
 103        int                             dev2;
 104        int                             mansw;
 105};
 106
 107static struct fsa9480_usbsw *chip;
 108
 109static int fsa9480_write_reg(struct i2c_client *client,
 110                int reg, int value)
 111{
 112        int ret;
 113
 114        ret = i2c_smbus_write_byte_data(client, reg, value);
 115
 116        if (ret < 0)
 117                dev_err(&client->dev, "%s: err %d\n", __func__, ret);
 118
 119        return ret;
 120}
 121
 122static int fsa9480_read_reg(struct i2c_client *client, int reg)
 123{
 124        int ret;
 125
 126        ret = i2c_smbus_read_byte_data(client, reg);
 127
 128        if (ret < 0)
 129                dev_err(&client->dev, "%s: err %d\n", __func__, ret);
 130
 131        return ret;
 132}
 133
 134static int fsa9480_read_irq(struct i2c_client *client, int *value)
 135{
 136        int ret;
 137
 138        ret = i2c_smbus_read_i2c_block_data(client,
 139                        FSA9480_REG_INT1, 2, (u8 *)value);
 140        *value &= 0xffff;
 141
 142        if (ret < 0)
 143                dev_err(&client->dev, "%s: err %d\n", __func__, ret);
 144
 145        return ret;
 146}
 147
 148static void fsa9480_set_switch(const char *buf)
 149{
 150        struct fsa9480_usbsw *usbsw = chip;
 151        struct i2c_client *client = usbsw->client;
 152        unsigned int value;
 153        unsigned int path = 0;
 154
 155        value = fsa9480_read_reg(client, FSA9480_REG_CTRL);
 156
 157        if (!strncmp(buf, "VAUDIO", 6)) {
 158                path = SW_VAUDIO;
 159                value &= ~CON_MANUAL_SW;
 160        } else if (!strncmp(buf, "UART", 4)) {
 161                path = SW_UART;
 162                value &= ~CON_MANUAL_SW;
 163        } else if (!strncmp(buf, "AUDIO", 5)) {
 164                path = SW_AUDIO;
 165                value &= ~CON_MANUAL_SW;
 166        } else if (!strncmp(buf, "DHOST", 5)) {
 167                path = SW_DHOST;
 168                value &= ~CON_MANUAL_SW;
 169        } else if (!strncmp(buf, "AUTO", 4)) {
 170                path = SW_AUTO;
 171                value |= CON_MANUAL_SW;
 172        } else {
 173                printk(KERN_ERR "Wrong command\n");
 174                return;
 175        }
 176
 177        usbsw->mansw = path;
 178        fsa9480_write_reg(client, FSA9480_REG_MANSW1, path);
 179        fsa9480_write_reg(client, FSA9480_REG_CTRL, value);
 180}
 181
 182static ssize_t fsa9480_get_switch(char *buf)
 183{
 184        struct fsa9480_usbsw *usbsw = chip;
 185        struct i2c_client *client = usbsw->client;
 186        unsigned int value;
 187
 188        value = fsa9480_read_reg(client, FSA9480_REG_MANSW1);
 189
 190        if (value == SW_VAUDIO)
 191                return sprintf(buf, "VAUDIO\n");
 192        else if (value == SW_UART)
 193                return sprintf(buf, "UART\n");
 194        else if (value == SW_AUDIO)
 195                return sprintf(buf, "AUDIO\n");
 196        else if (value == SW_DHOST)
 197                return sprintf(buf, "DHOST\n");
 198        else if (value == SW_AUTO)
 199                return sprintf(buf, "AUTO\n");
 200        else
 201                return sprintf(buf, "%x", value);
 202}
 203
 204static ssize_t fsa9480_show_device(struct device *dev,
 205                                   struct device_attribute *attr,
 206                                   char *buf)
 207{
 208        struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev);
 209        struct i2c_client *client = usbsw->client;
 210        int dev1, dev2;
 211
 212        dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
 213        dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
 214
 215        if (!dev1 && !dev2)
 216                return sprintf(buf, "NONE\n");
 217
 218        /* USB */
 219        if (dev1 & DEV_T1_USB_MASK || dev2 & DEV_T2_USB_MASK)
 220                return sprintf(buf, "USB\n");
 221
 222        /* UART */
 223        if (dev1 & DEV_T1_UART_MASK || dev2 & DEV_T2_UART_MASK)
 224                return sprintf(buf, "UART\n");
 225
 226        /* CHARGER */
 227        if (dev1 & DEV_T1_CHARGER_MASK)
 228                return sprintf(buf, "CHARGER\n");
 229
 230        /* JIG */
 231        if (dev2 & DEV_T2_JIG_MASK)
 232                return sprintf(buf, "JIG\n");
 233
 234        return sprintf(buf, "UNKNOWN\n");
 235}
 236
 237static ssize_t fsa9480_show_manualsw(struct device *dev,
 238                struct device_attribute *attr, char *buf)
 239{
 240        return fsa9480_get_switch(buf);
 241
 242}
 243
 244static ssize_t fsa9480_set_manualsw(struct device *dev,
 245                                    struct device_attribute *attr,
 246                                    const char *buf, size_t count)
 247{
 248        fsa9480_set_switch(buf);
 249
 250        return count;
 251}
 252
 253static DEVICE_ATTR(device, S_IRUGO, fsa9480_show_device, NULL);
 254static DEVICE_ATTR(switch, S_IRUGO | S_IWUSR,
 255                fsa9480_show_manualsw, fsa9480_set_manualsw);
 256
 257static struct attribute *fsa9480_attributes[] = {
 258        &dev_attr_device.attr,
 259        &dev_attr_switch.attr,
 260        NULL
 261};
 262
 263static const struct attribute_group fsa9480_group = {
 264        .attrs = fsa9480_attributes,
 265};
 266
 267static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw, int intr)
 268{
 269        int val1, val2, ctrl;
 270        struct fsa9480_platform_data *pdata = usbsw->pdata;
 271        struct i2c_client *client = usbsw->client;
 272
 273        val1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
 274        val2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
 275        ctrl = fsa9480_read_reg(client, FSA9480_REG_CTRL);
 276
 277        dev_info(&client->dev, "intr: 0x%x, dev1: 0x%x, dev2: 0x%x\n",
 278                        intr, val1, val2);
 279
 280        if (!intr)
 281                goto out;
 282
 283        if (intr & INT_ATTACH) {        /* Attached */
 284                /* USB */
 285                if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) {
 286                        if (pdata->usb_cb)
 287                                pdata->usb_cb(FSA9480_ATTACHED);
 288
 289                        if (usbsw->mansw) {
 290                                fsa9480_write_reg(client,
 291                                        FSA9480_REG_MANSW1, usbsw->mansw);
 292                        }
 293                }
 294
 295                /* UART */
 296                if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
 297                        if (pdata->uart_cb)
 298                                pdata->uart_cb(FSA9480_ATTACHED);
 299
 300                        if (!(ctrl & CON_MANUAL_SW)) {
 301                                fsa9480_write_reg(client,
 302                                        FSA9480_REG_MANSW1, SW_UART);
 303                        }
 304                }
 305
 306                /* CHARGER */
 307                if (val1 & DEV_T1_CHARGER_MASK) {
 308                        if (pdata->charger_cb)
 309                                pdata->charger_cb(FSA9480_ATTACHED);
 310                }
 311
 312                /* JIG */
 313                if (val2 & DEV_T2_JIG_MASK) {
 314                        if (pdata->jig_cb)
 315                                pdata->jig_cb(FSA9480_ATTACHED);
 316                }
 317        } else if (intr & INT_DETACH) { /* Detached */
 318                /* USB */
 319                if (usbsw->dev1 & DEV_T1_USB_MASK ||
 320                        usbsw->dev2 & DEV_T2_USB_MASK) {
 321                        if (pdata->usb_cb)
 322                                pdata->usb_cb(FSA9480_DETACHED);
 323                }
 324
 325                /* UART */
 326                if (usbsw->dev1 & DEV_T1_UART_MASK ||
 327                        usbsw->dev2 & DEV_T2_UART_MASK) {
 328                        if (pdata->uart_cb)
 329                                pdata->uart_cb(FSA9480_DETACHED);
 330                }
 331
 332                /* CHARGER */
 333                if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
 334                        if (pdata->charger_cb)
 335                                pdata->charger_cb(FSA9480_DETACHED);
 336                }
 337
 338                /* JIG */
 339                if (usbsw->dev2 & DEV_T2_JIG_MASK) {
 340                        if (pdata->jig_cb)
 341                                pdata->jig_cb(FSA9480_DETACHED);
 342                }
 343        }
 344
 345        usbsw->dev1 = val1;
 346        usbsw->dev2 = val2;
 347
 348out:
 349        ctrl &= ~CON_INT_MASK;
 350        fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl);
 351}
 352
 353static irqreturn_t fsa9480_irq_handler(int irq, void *data)
 354{
 355        struct fsa9480_usbsw *usbsw = data;
 356        struct i2c_client *client = usbsw->client;
 357        int intr;
 358
 359        /* clear interrupt */
 360        fsa9480_read_irq(client, &intr);
 361
 362        /* device detection */
 363        fsa9480_detect_dev(usbsw, intr);
 364
 365        return IRQ_HANDLED;
 366}
 367
 368static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw)
 369{
 370        struct fsa9480_platform_data *pdata = usbsw->pdata;
 371        struct i2c_client *client = usbsw->client;
 372        int ret;
 373        int intr;
 374        unsigned int ctrl = CON_MASK;
 375
 376        /* clear interrupt */
 377        fsa9480_read_irq(client, &intr);
 378
 379        /* unmask interrupt (attach/detach only) */
 380        fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0xfc);
 381        fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x1f);
 382
 383        usbsw->mansw = fsa9480_read_reg(client, FSA9480_REG_MANSW1);
 384
 385        if (usbsw->mansw)
 386                ctrl &= ~CON_MANUAL_SW; /* Manual Switching Mode */
 387
 388        fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl);
 389
 390        if (pdata && pdata->cfg_gpio)
 391                pdata->cfg_gpio();
 392
 393        if (client->irq) {
 394                ret = request_threaded_irq(client->irq, NULL,
 395                                fsa9480_irq_handler,
 396                                IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 397                                "fsa9480 micro USB", usbsw);
 398                if (ret) {
 399                        dev_err(&client->dev, "failed to request IRQ\n");
 400                        return ret;
 401                }
 402
 403                if (pdata)
 404                        device_init_wakeup(&client->dev, pdata->wakeup);
 405        }
 406
 407        return 0;
 408}
 409
 410static int fsa9480_probe(struct i2c_client *client,
 411                         const struct i2c_device_id *id)
 412{
 413        struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 414        struct fsa9480_usbsw *usbsw;
 415        int ret = 0;
 416
 417        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 418                return -EIO;
 419
 420        usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL);
 421        if (!usbsw) {
 422                dev_err(&client->dev, "failed to allocate driver data\n");
 423                return -ENOMEM;
 424        }
 425
 426        usbsw->client = client;
 427        usbsw->pdata = client->dev.platform_data;
 428
 429        chip = usbsw;
 430
 431        i2c_set_clientdata(client, usbsw);
 432
 433        ret = fsa9480_irq_init(usbsw);
 434        if (ret)
 435                goto fail1;
 436
 437        ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group);
 438        if (ret) {
 439                dev_err(&client->dev,
 440                                "failed to create fsa9480 attribute group\n");
 441                goto fail2;
 442        }
 443
 444        /* ADC Detect Time: 500ms */
 445        fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x6);
 446
 447        if (chip->pdata->reset_cb)
 448                chip->pdata->reset_cb();
 449
 450        /* device detection */
 451        fsa9480_detect_dev(usbsw, INT_ATTACH);
 452
 453        pm_runtime_set_active(&client->dev);
 454
 455        return 0;
 456
 457fail2:
 458        if (client->irq)
 459                free_irq(client->irq, usbsw);
 460fail1:
 461        kfree(usbsw);
 462        return ret;
 463}
 464
 465static int fsa9480_remove(struct i2c_client *client)
 466{
 467        struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
 468        if (client->irq)
 469                free_irq(client->irq, usbsw);
 470
 471        sysfs_remove_group(&client->dev.kobj, &fsa9480_group);
 472        device_init_wakeup(&client->dev, 0);
 473        kfree(usbsw);
 474        return 0;
 475}
 476
 477#ifdef CONFIG_PM_SLEEP
 478
 479static int fsa9480_suspend(struct device *dev)
 480{
 481        struct i2c_client *client = to_i2c_client(dev);
 482        struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
 483        struct fsa9480_platform_data *pdata = usbsw->pdata;
 484
 485        if (device_may_wakeup(&client->dev) && client->irq)
 486                enable_irq_wake(client->irq);
 487
 488        if (pdata->usb_power)
 489                pdata->usb_power(0);
 490
 491        return 0;
 492}
 493
 494static int fsa9480_resume(struct device *dev)
 495{
 496        struct i2c_client *client = to_i2c_client(dev);
 497        struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
 498        int dev1, dev2;
 499
 500        if (device_may_wakeup(&client->dev) && client->irq)
 501                disable_irq_wake(client->irq);
 502
 503        /*
 504         * Clear Pending interrupt. Note that detect_dev does what
 505         * the interrupt handler does. So, we don't miss pending and
 506         * we reenable interrupt if there is one.
 507         */
 508        fsa9480_read_reg(client, FSA9480_REG_INT1);
 509        fsa9480_read_reg(client, FSA9480_REG_INT2);
 510
 511        dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
 512        dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
 513
 514        /* device detection */
 515        fsa9480_detect_dev(usbsw, (dev1 || dev2) ? INT_ATTACH : INT_DETACH);
 516
 517        return 0;
 518}
 519
 520static SIMPLE_DEV_PM_OPS(fsa9480_pm_ops, fsa9480_suspend, fsa9480_resume);
 521#define FSA9480_PM_OPS (&fsa9480_pm_ops)
 522
 523#else
 524
 525#define FSA9480_PM_OPS NULL
 526
 527#endif /* CONFIG_PM_SLEEP */
 528
 529static const struct i2c_device_id fsa9480_id[] = {
 530        {"fsa9480", 0},
 531        {}
 532};
 533MODULE_DEVICE_TABLE(i2c, fsa9480_id);
 534
 535static struct i2c_driver fsa9480_i2c_driver = {
 536        .driver = {
 537                .name = "fsa9480",
 538                .pm = FSA9480_PM_OPS,
 539        },
 540        .probe = fsa9480_probe,
 541        .remove = fsa9480_remove,
 542        .id_table = fsa9480_id,
 543};
 544
 545module_i2c_driver(fsa9480_i2c_driver);
 546
 547MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
 548MODULE_DESCRIPTION("FSA9480 USB Switch driver");
 549MODULE_LICENSE("GPL");
 550