1 /* 2 * I2C driver for Maxim MAX8925 3 * 4 * Copyright (C) 2009 Marvell International Ltd. 5 * Haojian Zhuang <haojian.zhuang@marvell.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <linux/platform_device.h> 14 #include <linux/i2c.h> 15 #include <linux/mfd/max8925.h> 16 #include <linux/slab.h> 17 18 #define RTC_I2C_ADDR 0x68 19 #define ADC_I2C_ADDR 0x47 20 21 static inline int max8925_read_device(struct i2c_client *i2c, 22 int reg, int bytes, void *dest) 23 { 24 int ret; 25 26 if (bytes > 1) 27 ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest); 28 else { 29 ret = i2c_smbus_read_byte_data(i2c, reg); 30 if (ret < 0) 31 return ret; 32 *(unsigned char *)dest = (unsigned char)ret; 33 } 34 return ret; 35 } 36 37 static inline int max8925_write_device(struct i2c_client *i2c, 38 int reg, int bytes, void *src) 39 { 40 unsigned char buf[bytes + 1]; 41 int ret; 42 43 buf[0] = (unsigned char)reg; 44 memcpy(&buf[1], src, bytes); 45 46 ret = i2c_master_send(i2c, buf, bytes + 1); 47 if (ret < 0) 48 return ret; 49 return 0; 50 } 51 52 int max8925_reg_read(struct i2c_client *i2c, int reg) 53 { 54 struct max8925_chip *chip = i2c_get_clientdata(i2c); 55 unsigned char data = 0; 56 int ret; 57 58 mutex_lock(&chip->io_lock); 59 ret = max8925_read_device(i2c, reg, 1, &data); 60 mutex_unlock(&chip->io_lock); 61 62 if (ret < 0) 63 return ret; 64 else 65 return (int)data; 66 } 67 EXPORT_SYMBOL(max8925_reg_read); 68 69 int max8925_reg_write(struct i2c_client *i2c, int reg, 70 unsigned char data) 71 { 72 struct max8925_chip *chip = i2c_get_clientdata(i2c); 73 int ret; 74 75 mutex_lock(&chip->io_lock); 76 ret = max8925_write_device(i2c, reg, 1, &data); 77 mutex_unlock(&chip->io_lock); 78 79 return ret; 80 } 81 EXPORT_SYMBOL(max8925_reg_write); 82 83 int max8925_bulk_read(struct i2c_client *i2c, int reg, 84 int count, unsigned char *buf) 85 { 86 struct max8925_chip *chip = i2c_get_clientdata(i2c); 87 int ret; 88 89 mutex_lock(&chip->io_lock); 90 ret = max8925_read_device(i2c, reg, count, buf); 91 mutex_unlock(&chip->io_lock); 92 93 return ret; 94 } 95 EXPORT_SYMBOL(max8925_bulk_read); 96 97 int max8925_bulk_write(struct i2c_client *i2c, int reg, 98 int count, unsigned char *buf) 99 { 100 struct max8925_chip *chip = i2c_get_clientdata(i2c); 101 int ret; 102 103 mutex_lock(&chip->io_lock); 104 ret = max8925_write_device(i2c, reg, count, buf); 105 mutex_unlock(&chip->io_lock); 106 107 return ret; 108 } 109 EXPORT_SYMBOL(max8925_bulk_write); 110 111 int max8925_set_bits(struct i2c_client *i2c, int reg, 112 unsigned char mask, unsigned char data) 113 { 114 struct max8925_chip *chip = i2c_get_clientdata(i2c); 115 unsigned char value; 116 int ret; 117 118 mutex_lock(&chip->io_lock); 119 ret = max8925_read_device(i2c, reg, 1, &value); 120 if (ret < 0) 121 goto out; 122 value &= ~mask; 123 value |= data; 124 ret = max8925_write_device(i2c, reg, 1, &value); 125 out: 126 mutex_unlock(&chip->io_lock); 127 return ret; 128 } 129 EXPORT_SYMBOL(max8925_set_bits); 130 131 132 static const struct i2c_device_id max8925_id_table[] = { 133 { "max8925", 0 }, 134 { }, 135 }; 136 MODULE_DEVICE_TABLE(i2c, max8925_id_table); 137 138 static int __devinit max8925_probe(struct i2c_client *client, 139 const struct i2c_device_id *id) 140 { 141 struct max8925_platform_data *pdata = client->dev.platform_data; 142 static struct max8925_chip *chip; 143 144 if (!pdata) { 145 pr_info("%s: platform data is missing\n", __func__); 146 return -EINVAL; 147 } 148 149 chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL); 150 if (chip == NULL) 151 return -ENOMEM; 152 chip->i2c = client; 153 chip->dev = &client->dev; 154 i2c_set_clientdata(client, chip); 155 dev_set_drvdata(chip->dev, chip); 156 mutex_init(&chip->io_lock); 157 158 chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR); 159 i2c_set_clientdata(chip->rtc, chip); 160 161 chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); 162 i2c_set_clientdata(chip->adc, chip); 163 164 max8925_device_init(chip, pdata); 165 166 return 0; 167 } 168 169 static int __devexit max8925_remove(struct i2c_client *client) 170 { 171 struct max8925_chip *chip = i2c_get_clientdata(client); 172 173 max8925_device_exit(chip); 174 i2c_unregister_device(chip->adc); 175 i2c_unregister_device(chip->rtc); 176 kfree(chip); 177 return 0; 178 } 179 180 static struct i2c_driver max8925_driver = { 181 .driver = { 182 .name = "max8925", 183 .owner = THIS_MODULE, 184 }, 185 .probe = max8925_probe, 186 .remove = __devexit_p(max8925_remove), 187 .id_table = max8925_id_table, 188 }; 189 190 static int __init max8925_i2c_init(void) 191 { 192 int ret; 193 194 ret = i2c_add_driver(&max8925_driver); 195 if (ret != 0) 196 pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); 197 return ret; 198 } 199 subsys_initcall(max8925_i2c_init); 200 201 static void __exit max8925_i2c_exit(void) 202 { 203 i2c_del_driver(&max8925_driver); 204 } 205 module_exit(max8925_i2c_exit); 206 207 MODULE_DESCRIPTION("I2C Driver for Maxim 8925"); 208 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 209 MODULE_LICENSE("GPL"); 210