Blame view
drivers/mfd/max8925-i2c.c
5.88 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
d50f8f339 mfd: Initial max8... |
2 3 4 5 6 |
/* * I2C driver for Maxim MAX8925 * * Copyright (C) 2009 Marvell International Ltd. * Haojian Zhuang <haojian.zhuang@marvell.com> |
d50f8f339 mfd: Initial max8... |
7 8 |
*/ #include <linux/kernel.h> |
9eb5f9ba1 mfd: max8925-i2c:... |
9 |
#include <linux/init.h> |
d50f8f339 mfd: Initial max8... |
10 11 12 |
#include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/mfd/max8925.h> |
5a0e3ad6a include cleanup: ... |
13 |
#include <linux/slab.h> |
d50f8f339 mfd: Initial max8... |
14 |
|
b13c0df51 mfd: Update i2c d... |
15 16 |
#define RTC_I2C_ADDR 0x68 #define ADC_I2C_ADDR 0x47 |
d50f8f339 mfd: Initial max8... |
17 18 19 |
static inline int max8925_read_device(struct i2c_client *i2c, int reg, int bytes, void *dest) { |
d50f8f339 mfd: Initial max8... |
20 |
int ret; |
b13c0df51 mfd: Update i2c d... |
21 22 23 24 25 26 27 28 29 |
if (bytes > 1) ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest); else { ret = i2c_smbus_read_byte_data(i2c, reg); if (ret < 0) return ret; *(unsigned char *)dest = (unsigned char)ret; } return ret; |
d50f8f339 mfd: Initial max8... |
30 31 32 33 34 |
} static inline int max8925_write_device(struct i2c_client *i2c, int reg, int bytes, void *src) { |
87bd1c925 mfd: max8925-i2c:... |
35 |
unsigned char buf[9]; |
d50f8f339 mfd: Initial max8... |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
int ret; buf[0] = (unsigned char)reg; memcpy(&buf[1], src, bytes); ret = i2c_master_send(i2c, buf, bytes + 1); if (ret < 0) return ret; return 0; } int max8925_reg_read(struct i2c_client *i2c, int reg) { struct max8925_chip *chip = i2c_get_clientdata(i2c); |
b13c0df51 mfd: Update i2c d... |
50 |
unsigned char data = 0; |
d50f8f339 mfd: Initial max8... |
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
int ret; mutex_lock(&chip->io_lock); ret = max8925_read_device(i2c, reg, 1, &data); mutex_unlock(&chip->io_lock); if (ret < 0) return ret; else return (int)data; } EXPORT_SYMBOL(max8925_reg_read); int max8925_reg_write(struct i2c_client *i2c, int reg, unsigned char data) { struct max8925_chip *chip = i2c_get_clientdata(i2c); int ret; mutex_lock(&chip->io_lock); ret = max8925_write_device(i2c, reg, 1, &data); mutex_unlock(&chip->io_lock); return ret; } EXPORT_SYMBOL(max8925_reg_write); int max8925_bulk_read(struct i2c_client *i2c, int reg, int count, unsigned char *buf) { struct max8925_chip *chip = i2c_get_clientdata(i2c); int ret; mutex_lock(&chip->io_lock); ret = max8925_read_device(i2c, reg, count, buf); mutex_unlock(&chip->io_lock); return ret; } EXPORT_SYMBOL(max8925_bulk_read); int max8925_bulk_write(struct i2c_client *i2c, int reg, int count, unsigned char *buf) { struct max8925_chip *chip = i2c_get_clientdata(i2c); int ret; mutex_lock(&chip->io_lock); ret = max8925_write_device(i2c, reg, count, buf); mutex_unlock(&chip->io_lock); return ret; } EXPORT_SYMBOL(max8925_bulk_write); int max8925_set_bits(struct i2c_client *i2c, int reg, unsigned char mask, unsigned char data) { struct max8925_chip *chip = i2c_get_clientdata(i2c); unsigned char value; int ret; mutex_lock(&chip->io_lock); ret = max8925_read_device(i2c, reg, 1, &value); if (ret < 0) goto out; value &= ~mask; value |= data; ret = max8925_write_device(i2c, reg, 1, &value); out: mutex_unlock(&chip->io_lock); return ret; } EXPORT_SYMBOL(max8925_set_bits); static const struct i2c_device_id max8925_id_table[] = { { "max8925", 0 }, |
b13c0df51 mfd: Update i2c d... |
129 |
{ }, |
d50f8f339 mfd: Initial max8... |
130 |
}; |
d50f8f339 mfd: Initial max8... |
131 |
|
4e405ae25 mfd: max8925: Add... |
132 133 134 135 136 137 138 139 140 141 142 143 144 |
static int max8925_dt_init(struct device_node *np, struct device *dev, struct max8925_platform_data *pdata) { int ret; ret = of_property_read_u32(np, "maxim,tsc-irq", &pdata->tsc_irq); if (ret) { dev_err(dev, "Not found maxim,tsc-irq property "); return -EINVAL; } return 0; } |
f791be492 mfd: remove use o... |
145 |
static int max8925_probe(struct i2c_client *client, |
d50f8f339 mfd: Initial max8... |
146 147 |
const struct i2c_device_id *id) { |
334a41ce9 mfd: Use dev_get_... |
148 |
struct max8925_platform_data *pdata = dev_get_platdata(&client->dev); |
095307511 mfd: max8925-i2c:... |
149 |
struct max8925_chip *chip; |
4e405ae25 mfd: max8925: Add... |
150 151 152 153 154 155 156 157 158 159 160 161 162 |
struct device_node *node = client->dev.of_node; if (node && !pdata) { /* parse DT to get platform data */ pdata = devm_kzalloc(&client->dev, sizeof(struct max8925_platform_data), GFP_KERNEL); if (!pdata) return -ENOMEM; if (max8925_dt_init(node, &client->dev, pdata)) return -EINVAL; } else if (!pdata) { |
d50f8f339 mfd: Initial max8... |
163 164 165 166 |
pr_info("%s: platform data is missing ", __func__); return -EINVAL; } |
d50f8f339 mfd: Initial max8... |
167 |
|
02c7d8489 mfd: max8925: Con... |
168 169 |
chip = devm_kzalloc(&client->dev, sizeof(struct max8925_chip), GFP_KERNEL); |
d50f8f339 mfd: Initial max8... |
170 171 172 |
if (chip == NULL) return -ENOMEM; chip->i2c = client; |
d50f8f339 mfd: Initial max8... |
173 |
chip->dev = &client->dev; |
b13c0df51 mfd: Update i2c d... |
174 |
i2c_set_clientdata(client, chip); |
d50f8f339 mfd: Initial max8... |
175 |
dev_set_drvdata(chip->dev, chip); |
b13c0df51 mfd: Update i2c d... |
176 |
mutex_init(&chip->io_lock); |
ddbf6ffeb mfd: max8925-i2c:... |
177 178 |
chip->rtc = i2c_new_dummy_device(chip->i2c->adapter, RTC_I2C_ADDR); if (IS_ERR(chip->rtc)) { |
96cf3dedc mfd: max8925: Fix... |
179 180 |
dev_err(chip->dev, "Failed to allocate I2C device for RTC "); |
ddbf6ffeb mfd: max8925-i2c:... |
181 |
return PTR_ERR(chip->rtc); |
96cf3dedc mfd: max8925: Fix... |
182 |
} |
b13c0df51 mfd: Update i2c d... |
183 |
i2c_set_clientdata(chip->rtc, chip); |
ddbf6ffeb mfd: max8925-i2c:... |
184 185 |
chip->adc = i2c_new_dummy_device(chip->i2c->adapter, ADC_I2C_ADDR); if (IS_ERR(chip->adc)) { |
96cf3dedc mfd: max8925: Fix... |
186 187 188 |
dev_err(chip->dev, "Failed to allocate I2C device for ADC "); i2c_unregister_device(chip->rtc); |
ddbf6ffeb mfd: max8925-i2c:... |
189 |
return PTR_ERR(chip->adc); |
96cf3dedc mfd: max8925: Fix... |
190 |
} |
b13c0df51 mfd: Update i2c d... |
191 |
i2c_set_clientdata(chip->adc, chip); |
ba74e80eb mfd: Add pm ops t... |
192 |
device_init_wakeup(&client->dev, 1); |
d50f8f339 mfd: Initial max8... |
193 194 195 196 |
max8925_device_init(chip, pdata); return 0; } |
4740f73fe mfd: remove use o... |
197 |
static int max8925_remove(struct i2c_client *client) |
d50f8f339 mfd: Initial max8... |
198 199 200 201 |
{ struct max8925_chip *chip = i2c_get_clientdata(client); max8925_device_exit(chip); |
b13c0df51 mfd: Update i2c d... |
202 203 |
i2c_unregister_device(chip->adc); i2c_unregister_device(chip->rtc); |
d50f8f339 mfd: Initial max8... |
204 205 |
return 0; } |
ba74e80eb mfd: Add pm ops t... |
206 207 208 |
#ifdef CONFIG_PM_SLEEP static int max8925_suspend(struct device *dev) { |
1b5420e1f mfd: Use to_i2c_c... |
209 |
struct i2c_client *client = to_i2c_client(dev); |
ba74e80eb mfd: Add pm ops t... |
210 211 212 213 214 215 216 217 218 |
struct max8925_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev) && chip->wakeup_flag) enable_irq_wake(chip->core_irq); return 0; } static int max8925_resume(struct device *dev) { |
1b5420e1f mfd: Use to_i2c_c... |
219 |
struct i2c_client *client = to_i2c_client(dev); |
ba74e80eb mfd: Add pm ops t... |
220 221 222 223 224 225 226 227 228 |
struct max8925_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev) && chip->wakeup_flag) disable_irq_wake(chip->core_irq); return 0; } #endif static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume); |
4e405ae25 mfd: max8925: Add... |
229 230 231 232 |
static const struct of_device_id max8925_dt_ids[] = { { .compatible = "maxim,max8925", }, {}, }; |
4e405ae25 mfd: max8925: Add... |
233 |
|
d50f8f339 mfd: Initial max8... |
234 235 236 |
static struct i2c_driver max8925_driver = { .driver = { .name = "max8925", |
ba74e80eb mfd: Add pm ops t... |
237 |
.pm = &max8925_pm_ops, |
52c2c6ebf mfd: max8925: Rem... |
238 |
.of_match_table = max8925_dt_ids, |
d50f8f339 mfd: Initial max8... |
239 240 |
}, .probe = max8925_probe, |
84449216b mfd: remove use o... |
241 |
.remove = max8925_remove, |
d50f8f339 mfd: Initial max8... |
242 243 244 245 246 247 |
.id_table = max8925_id_table, }; static int __init max8925_i2c_init(void) { int ret; |
4ed8f7182 mfd: max8925-i2c:... |
248 |
|
d50f8f339 mfd: Initial max8... |
249 250 251 252 |
ret = i2c_add_driver(&max8925_driver); if (ret != 0) pr_err("Failed to register MAX8925 I2C driver: %d ", ret); |
4ed8f7182 mfd: max8925-i2c:... |
253 |
|
d50f8f339 mfd: Initial max8... |
254 255 256 |
return ret; } subsys_initcall(max8925_i2c_init); |