linux/drivers/mfd/wm831x-i2c.c
<<
>>
Prefs
   1/*
   2 * wm831x-i2c.c  --  I2C access for Wolfson WM831x PMICs
   3 *
   4 * Copyright 2009,2010 Wolfson Microelectronics PLC.
   5 *
   6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   7 *
   8 *  This program is free software; you can redistribute  it and/or modify it
   9 *  under  the terms of  the GNU General  Public License as published by the
  10 *  Free Software Foundation;  either version 2 of the  License, or (at your
  11 *  option) any later version.
  12 *
  13 */
  14
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/i2c.h>
  18#include <linux/delay.h>
  19#include <linux/mfd/core.h>
  20#include <linux/slab.h>
  21
  22#include <linux/mfd/wm831x/core.h>
  23#include <linux/mfd/wm831x/pdata.h>
  24
  25static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
  26                                  int bytes, void *dest)
  27{
  28        struct i2c_client *i2c = wm831x->control_data;
  29        int ret;
  30        u16 r = cpu_to_be16(reg);
  31
  32        ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
  33        if (ret < 0)
  34                return ret;
  35        if (ret != 2)
  36                return -EIO;
  37
  38        ret = i2c_master_recv(i2c, dest, bytes);
  39        if (ret < 0)
  40                return ret;
  41        if (ret != bytes)
  42                return -EIO;
  43        return 0;
  44}
  45
  46/* Currently we allocate the write buffer on the stack; this is OK for
  47 * small writes - if we need to do large writes this will need to be
  48 * revised.
  49 */
  50static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
  51                                   int bytes, void *src)
  52{
  53        struct i2c_client *i2c = wm831x->control_data;
  54        struct i2c_msg xfer[2];
  55        int ret;
  56
  57        reg = cpu_to_be16(reg);
  58
  59        xfer[0].addr = i2c->addr;
  60        xfer[0].flags = 0;
  61        xfer[0].len = 2;
  62        xfer[0].buf = (char *)&reg;
  63
  64        xfer[1].addr = i2c->addr;
  65        xfer[1].flags = I2C_M_NOSTART;
  66        xfer[1].len = bytes;
  67        xfer[1].buf = (char *)src;
  68
  69        ret = i2c_transfer(i2c->adapter, xfer, 2);
  70        if (ret < 0)
  71                return ret;
  72        if (ret != 2)
  73                return -EIO;
  74
  75        return 0;
  76}
  77
  78static int wm831x_i2c_probe(struct i2c_client *i2c,
  79                            const struct i2c_device_id *id)
  80{
  81        struct wm831x *wm831x;
  82
  83        wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
  84        if (wm831x == NULL)
  85                return -ENOMEM;
  86
  87        i2c_set_clientdata(i2c, wm831x);
  88        wm831x->dev = &i2c->dev;
  89        wm831x->control_data = i2c;
  90        wm831x->read_dev = wm831x_i2c_read_device;
  91        wm831x->write_dev = wm831x_i2c_write_device;
  92
  93        return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
  94}
  95
  96static int wm831x_i2c_remove(struct i2c_client *i2c)
  97{
  98        struct wm831x *wm831x = i2c_get_clientdata(i2c);
  99
 100        wm831x_device_exit(wm831x);
 101
 102        return 0;
 103}
 104
 105static int wm831x_i2c_suspend(struct device *dev)
 106{
 107        struct wm831x *wm831x = dev_get_drvdata(dev);
 108
 109        return wm831x_device_suspend(wm831x);
 110}
 111
 112static const struct i2c_device_id wm831x_i2c_id[] = {
 113        { "wm8310", WM8310 },
 114        { "wm8311", WM8311 },
 115        { "wm8312", WM8312 },
 116        { "wm8320", WM8320 },
 117        { "wm8321", WM8321 },
 118        { "wm8325", WM8325 },
 119        { "wm8326", WM8326 },
 120        { }
 121};
 122MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
 123
 124static const struct dev_pm_ops wm831x_pm_ops = {
 125        .suspend = wm831x_i2c_suspend,
 126};
 127
 128static struct i2c_driver wm831x_i2c_driver = {
 129        .driver = {
 130                .name = "wm831x",
 131                .owner = THIS_MODULE,
 132                .pm = &wm831x_pm_ops,
 133        },
 134        .probe = wm831x_i2c_probe,
 135        .remove = wm831x_i2c_remove,
 136        .id_table = wm831x_i2c_id,
 137};
 138
 139static int __init wm831x_i2c_init(void)
 140{
 141        int ret;
 142
 143        ret = i2c_add_driver(&wm831x_i2c_driver);
 144        if (ret != 0)
 145                pr_err("Failed to register wm831x I2C driver: %d\n", ret);
 146
 147        return ret;
 148}
 149subsys_initcall(wm831x_i2c_init);
 150
 151static void __exit wm831x_i2c_exit(void)
 152{
 153        i2c_del_driver(&wm831x_i2c_driver);
 154}
 155module_exit(wm831x_i2c_exit);
 156