1ff606677SJean Delvare /* 2ff606677SJean Delvare * drivers/hwmon/lis3lv02d_i2c.c 3ff606677SJean Delvare * 4ff606677SJean Delvare * Implements I2C interface for lis3lv02d (STMicroelectronics) accelerometer. 5ff606677SJean Delvare * Driver is based on corresponding SPI driver written by Daniel Mack 6ff606677SJean Delvare * (lis3lv02d_spi.c (C) 2009 Daniel Mack <daniel@caiaq.de> ). 7ff606677SJean Delvare * 8ff606677SJean Delvare * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 9ff606677SJean Delvare * 10ff606677SJean Delvare * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> 11ff606677SJean Delvare * 12ff606677SJean Delvare * This program is free software; you can redistribute it and/or 13ff606677SJean Delvare * modify it under the terms of the GNU General Public License 14ff606677SJean Delvare * version 2 as published by the Free Software Foundation. 15ff606677SJean Delvare * 16ff606677SJean Delvare * This program is distributed in the hope that it will be useful, but 17ff606677SJean Delvare * WITHOUT ANY WARRANTY; without even the implied warranty of 18ff606677SJean Delvare * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19ff606677SJean Delvare * General Public License for more details. 20ff606677SJean Delvare * 21ff606677SJean Delvare * You should have received a copy of the GNU General Public License 22ff606677SJean Delvare * along with this program; if not, write to the Free Software 23ff606677SJean Delvare * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 24ff606677SJean Delvare * 02110-1301 USA 25ff606677SJean Delvare */ 26ff606677SJean Delvare 27ff606677SJean Delvare #include <linux/module.h> 28ff606677SJean Delvare #include <linux/kernel.h> 29ff606677SJean Delvare #include <linux/init.h> 30ff606677SJean Delvare #include <linux/err.h> 31ff606677SJean Delvare #include <linux/i2c.h> 32ff606677SJean Delvare #include <linux/pm_runtime.h> 33ff606677SJean Delvare #include <linux/delay.h> 34ff606677SJean Delvare #include "lis3lv02d.h" 35ff606677SJean Delvare 36ff606677SJean Delvare #define DRV_NAME "lis3lv02d_i2c" 37ff606677SJean Delvare 38ff606677SJean Delvare static const char reg_vdd[] = "Vdd"; 39ff606677SJean Delvare static const char reg_vdd_io[] = "Vdd_IO"; 40ff606677SJean Delvare 41ff606677SJean Delvare static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state) 42ff606677SJean Delvare { 43ff606677SJean Delvare int ret; 44ff606677SJean Delvare if (state == LIS3_REG_OFF) { 45ff606677SJean Delvare ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators), 46ff606677SJean Delvare lis3->regulators); 47ff606677SJean Delvare } else { 48ff606677SJean Delvare ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators), 49ff606677SJean Delvare lis3->regulators); 50ff606677SJean Delvare /* Chip needs time to wakeup. Not mentioned in datasheet */ 51ff606677SJean Delvare usleep_range(10000, 20000); 52ff606677SJean Delvare } 53ff606677SJean Delvare return ret; 54ff606677SJean Delvare } 55ff606677SJean Delvare 56ff606677SJean Delvare static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value) 57ff606677SJean Delvare { 58ff606677SJean Delvare struct i2c_client *c = lis3->bus_priv; 59ff606677SJean Delvare return i2c_smbus_write_byte_data(c, reg, value); 60ff606677SJean Delvare } 61ff606677SJean Delvare 62ff606677SJean Delvare static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v) 63ff606677SJean Delvare { 64ff606677SJean Delvare struct i2c_client *c = lis3->bus_priv; 65ff606677SJean Delvare *v = i2c_smbus_read_byte_data(c, reg); 66ff606677SJean Delvare return 0; 67ff606677SJean Delvare } 68ff606677SJean Delvare 69ff606677SJean Delvare static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len, 70ff606677SJean Delvare u8 *v) 71ff606677SJean Delvare { 72ff606677SJean Delvare struct i2c_client *c = lis3->bus_priv; 73ff606677SJean Delvare reg |= (1 << 7); /* 7th bit enables address auto incrementation */ 74ff606677SJean Delvare return i2c_smbus_read_i2c_block_data(c, reg, len, v); 75ff606677SJean Delvare } 76ff606677SJean Delvare 77ff606677SJean Delvare static int lis3_i2c_init(struct lis3lv02d *lis3) 78ff606677SJean Delvare { 79ff606677SJean Delvare u8 reg; 80ff606677SJean Delvare int ret; 81ff606677SJean Delvare 82ff606677SJean Delvare if (lis3->reg_ctrl) 83ff606677SJean Delvare lis3_reg_ctrl(lis3, LIS3_REG_ON); 84ff606677SJean Delvare 85ff606677SJean Delvare lis3->read(lis3, WHO_AM_I, ®); 86ff606677SJean Delvare if (reg != lis3->whoami) 87ff606677SJean Delvare printk(KERN_ERR "lis3: power on failure\n"); 88ff606677SJean Delvare 89ff606677SJean Delvare /* power up the device */ 90ff606677SJean Delvare ret = lis3->read(lis3, CTRL_REG1, ®); 91ff606677SJean Delvare if (ret < 0) 92ff606677SJean Delvare return ret; 93ff606677SJean Delvare 94ff606677SJean Delvare reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen; 95ff606677SJean Delvare return lis3->write(lis3, CTRL_REG1, reg); 96ff606677SJean Delvare } 97ff606677SJean Delvare 98ff606677SJean Delvare /* Default axis mapping but it can be overwritten by platform data */ 99ff606677SJean Delvare static union axis_conversion lis3lv02d_axis_map = 100ff606677SJean Delvare { .as_array = { LIS3_DEV_X, LIS3_DEV_Y, LIS3_DEV_Z } }; 101ff606677SJean Delvare 102ff606677SJean Delvare static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, 103ff606677SJean Delvare const struct i2c_device_id *id) 104ff606677SJean Delvare { 105ff606677SJean Delvare int ret = 0; 106ff606677SJean Delvare struct lis3lv02d_platform_data *pdata = client->dev.platform_data; 107ff606677SJean Delvare 108ff606677SJean Delvare if (pdata) { 109ff606677SJean Delvare /* Regulator control is optional */ 110ff606677SJean Delvare if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL) 111ff606677SJean Delvare lis3_dev.reg_ctrl = lis3_reg_ctrl; 112ff606677SJean Delvare 113ff606677SJean Delvare if ((pdata->driver_features & LIS3_USE_BLOCK_READ) && 114ff606677SJean Delvare (i2c_check_functionality(client->adapter, 115ff606677SJean Delvare I2C_FUNC_SMBUS_I2C_BLOCK))) 116ff606677SJean Delvare lis3_dev.blkread = lis3_i2c_blockread; 117ff606677SJean Delvare 118ff606677SJean Delvare if (pdata->axis_x) 119ff606677SJean Delvare lis3lv02d_axis_map.x = pdata->axis_x; 120ff606677SJean Delvare 121ff606677SJean Delvare if (pdata->axis_y) 122ff606677SJean Delvare lis3lv02d_axis_map.y = pdata->axis_y; 123ff606677SJean Delvare 124ff606677SJean Delvare if (pdata->axis_z) 125ff606677SJean Delvare lis3lv02d_axis_map.z = pdata->axis_z; 126ff606677SJean Delvare 127ff606677SJean Delvare if (pdata->setup_resources) 128ff606677SJean Delvare ret = pdata->setup_resources(); 129ff606677SJean Delvare 130ff606677SJean Delvare if (ret) 131ff606677SJean Delvare goto fail; 132ff606677SJean Delvare } 133ff606677SJean Delvare 134ff606677SJean Delvare if (lis3_dev.reg_ctrl) { 135ff606677SJean Delvare lis3_dev.regulators[0].supply = reg_vdd; 136ff606677SJean Delvare lis3_dev.regulators[1].supply = reg_vdd_io; 137ff606677SJean Delvare ret = regulator_bulk_get(&client->dev, 138ff606677SJean Delvare ARRAY_SIZE(lis3_dev.regulators), 139ff606677SJean Delvare lis3_dev.regulators); 140ff606677SJean Delvare if (ret < 0) 141ff606677SJean Delvare goto fail; 142ff606677SJean Delvare } 143ff606677SJean Delvare 144ff606677SJean Delvare lis3_dev.pdata = pdata; 145ff606677SJean Delvare lis3_dev.bus_priv = client; 146ff606677SJean Delvare lis3_dev.init = lis3_i2c_init; 147ff606677SJean Delvare lis3_dev.read = lis3_i2c_read; 148ff606677SJean Delvare lis3_dev.write = lis3_i2c_write; 149ff606677SJean Delvare lis3_dev.irq = client->irq; 150ff606677SJean Delvare lis3_dev.ac = lis3lv02d_axis_map; 151ff606677SJean Delvare lis3_dev.pm_dev = &client->dev; 152ff606677SJean Delvare 153ff606677SJean Delvare i2c_set_clientdata(client, &lis3_dev); 154ff606677SJean Delvare 155ff606677SJean Delvare /* Provide power over the init call */ 156ff606677SJean Delvare if (lis3_dev.reg_ctrl) 157ff606677SJean Delvare lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON); 158ff606677SJean Delvare 159ff606677SJean Delvare ret = lis3lv02d_init_device(&lis3_dev); 160ff606677SJean Delvare 161ff606677SJean Delvare if (lis3_dev.reg_ctrl) 162ff606677SJean Delvare lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF); 163ff606677SJean Delvare 1640021586bSÉric Piel if (ret) 1650021586bSÉric Piel goto fail2; 166ff606677SJean Delvare return 0; 1670021586bSÉric Piel 1680021586bSÉric Piel fail2: 1690021586bSÉric Piel regulator_bulk_free(ARRAY_SIZE(lis3_dev.regulators), 1700021586bSÉric Piel lis3_dev.regulators); 171ff606677SJean Delvare fail: 172ff606677SJean Delvare if (pdata && pdata->release_resources) 173ff606677SJean Delvare pdata->release_resources(); 174ff606677SJean Delvare return ret; 175ff606677SJean Delvare } 176ff606677SJean Delvare 177ff606677SJean Delvare static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) 178ff606677SJean Delvare { 179ff606677SJean Delvare struct lis3lv02d *lis3 = i2c_get_clientdata(client); 180ff606677SJean Delvare struct lis3lv02d_platform_data *pdata = client->dev.platform_data; 181ff606677SJean Delvare 182ff606677SJean Delvare if (pdata && pdata->release_resources) 183ff606677SJean Delvare pdata->release_resources(); 184ff606677SJean Delvare 185*e1e5687dSÉric Piel lis3lv02d_joystick_disable(lis3); 186ff606677SJean Delvare lis3lv02d_remove_fs(&lis3_dev); 187ff606677SJean Delvare 188ff606677SJean Delvare if (lis3_dev.reg_ctrl) 189ff606677SJean Delvare regulator_bulk_free(ARRAY_SIZE(lis3->regulators), 190ff606677SJean Delvare lis3_dev.regulators); 191ff606677SJean Delvare return 0; 192ff606677SJean Delvare } 193ff606677SJean Delvare 194ff606677SJean Delvare #ifdef CONFIG_PM_SLEEP 195ff606677SJean Delvare static int lis3lv02d_i2c_suspend(struct device *dev) 196ff606677SJean Delvare { 197ff606677SJean Delvare struct i2c_client *client = container_of(dev, struct i2c_client, dev); 198ff606677SJean Delvare struct lis3lv02d *lis3 = i2c_get_clientdata(client); 199ff606677SJean Delvare 200ff606677SJean Delvare if (!lis3->pdata || !lis3->pdata->wakeup_flags) 201ff606677SJean Delvare lis3lv02d_poweroff(lis3); 202ff606677SJean Delvare return 0; 203ff606677SJean Delvare } 204ff606677SJean Delvare 205ff606677SJean Delvare static int lis3lv02d_i2c_resume(struct device *dev) 206ff606677SJean Delvare { 207ff606677SJean Delvare struct i2c_client *client = container_of(dev, struct i2c_client, dev); 208ff606677SJean Delvare struct lis3lv02d *lis3 = i2c_get_clientdata(client); 209ff606677SJean Delvare 210ff606677SJean Delvare /* 211ff606677SJean Delvare * pm_runtime documentation says that devices should always 212ff606677SJean Delvare * be powered on at resume. Pm_runtime turns them off after system 213ff606677SJean Delvare * wide resume is complete. 214ff606677SJean Delvare */ 215ff606677SJean Delvare if (!lis3->pdata || !lis3->pdata->wakeup_flags || 216ff606677SJean Delvare pm_runtime_suspended(dev)) 217ff606677SJean Delvare lis3lv02d_poweron(lis3); 218ff606677SJean Delvare 219ff606677SJean Delvare return 0; 220ff606677SJean Delvare } 221ff606677SJean Delvare #endif /* CONFIG_PM_SLEEP */ 222ff606677SJean Delvare 223ff606677SJean Delvare #ifdef CONFIG_PM_RUNTIME 224ff606677SJean Delvare static int lis3_i2c_runtime_suspend(struct device *dev) 225ff606677SJean Delvare { 226ff606677SJean Delvare struct i2c_client *client = container_of(dev, struct i2c_client, dev); 227ff606677SJean Delvare struct lis3lv02d *lis3 = i2c_get_clientdata(client); 228ff606677SJean Delvare 229ff606677SJean Delvare lis3lv02d_poweroff(lis3); 230ff606677SJean Delvare return 0; 231ff606677SJean Delvare } 232ff606677SJean Delvare 233ff606677SJean Delvare static int lis3_i2c_runtime_resume(struct device *dev) 234ff606677SJean Delvare { 235ff606677SJean Delvare struct i2c_client *client = container_of(dev, struct i2c_client, dev); 236ff606677SJean Delvare struct lis3lv02d *lis3 = i2c_get_clientdata(client); 237ff606677SJean Delvare 238ff606677SJean Delvare lis3lv02d_poweron(lis3); 239ff606677SJean Delvare return 0; 240ff606677SJean Delvare } 241ff606677SJean Delvare #endif /* CONFIG_PM_RUNTIME */ 242ff606677SJean Delvare 243ff606677SJean Delvare static const struct i2c_device_id lis3lv02d_id[] = { 244ff606677SJean Delvare {"lis3lv02d", 0 }, 245ff606677SJean Delvare {} 246ff606677SJean Delvare }; 247ff606677SJean Delvare 248ff606677SJean Delvare MODULE_DEVICE_TABLE(i2c, lis3lv02d_id); 249ff606677SJean Delvare 250ff606677SJean Delvare static const struct dev_pm_ops lis3_pm_ops = { 251ff606677SJean Delvare SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend, 252ff606677SJean Delvare lis3lv02d_i2c_resume) 253ff606677SJean Delvare SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend, 254ff606677SJean Delvare lis3_i2c_runtime_resume, 255ff606677SJean Delvare NULL) 256ff606677SJean Delvare }; 257ff606677SJean Delvare 258ff606677SJean Delvare static struct i2c_driver lis3lv02d_i2c_driver = { 259ff606677SJean Delvare .driver = { 260ff606677SJean Delvare .name = DRV_NAME, 261ff606677SJean Delvare .owner = THIS_MODULE, 262ff606677SJean Delvare .pm = &lis3_pm_ops, 263ff606677SJean Delvare }, 264ff606677SJean Delvare .probe = lis3lv02d_i2c_probe, 265ff606677SJean Delvare .remove = __devexit_p(lis3lv02d_i2c_remove), 266ff606677SJean Delvare .id_table = lis3lv02d_id, 267ff606677SJean Delvare }; 268ff606677SJean Delvare 269ff606677SJean Delvare static int __init lis3lv02d_init(void) 270ff606677SJean Delvare { 271ff606677SJean Delvare return i2c_add_driver(&lis3lv02d_i2c_driver); 272ff606677SJean Delvare } 273ff606677SJean Delvare 274ff606677SJean Delvare static void __exit lis3lv02d_exit(void) 275ff606677SJean Delvare { 276ff606677SJean Delvare i2c_del_driver(&lis3lv02d_i2c_driver); 277ff606677SJean Delvare } 278ff606677SJean Delvare 279ff606677SJean Delvare MODULE_AUTHOR("Nokia Corporation"); 280ff606677SJean Delvare MODULE_DESCRIPTION("lis3lv02d I2C interface"); 281ff606677SJean Delvare MODULE_LICENSE("GPL"); 282ff606677SJean Delvare 283ff606677SJean Delvare module_init(lis3lv02d_init); 284ff606677SJean Delvare module_exit(lis3lv02d_exit); 285