1d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang/*
2d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang * I2C driver for Maxim MAX8925
3d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang *
4d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang * Copyright (C) 2009 Marvell International Ltd.
5d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang *	Haojian Zhuang <haojian.zhuang@marvell.com>
6d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang *
7d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang * This program is free software; you can redistribute it and/or modify
8d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang * it under the terms of the GNU General Public License version 2 as
9d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang * published by the Free Software Foundation.
10d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang */
11d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang#include <linux/kernel.h>
12d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang#include <linux/module.h>
13d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang#include <linux/platform_device.h>
14d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang#include <linux/i2c.h>
15d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang#include <linux/mfd/max8925.h>
165a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
17d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
18b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang#define RTC_I2C_ADDR		0x68
19b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang#define ADC_I2C_ADDR		0x47
20b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang
21d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangstatic inline int max8925_read_device(struct i2c_client *i2c,
22d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang				      int reg, int bytes, void *dest)
23d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
24d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
25d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
26b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	if (bytes > 1)
27b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang		ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
28b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	else {
29b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang		ret = i2c_smbus_read_byte_data(i2c, reg);
30b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang		if (ret < 0)
31b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang			return ret;
32b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang		*(unsigned char *)dest = (unsigned char)ret;
33b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	}
34b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	return ret;
35d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
36d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
37d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangstatic inline int max8925_write_device(struct i2c_client *i2c,
38d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang				       int reg, int bytes, void *src)
39d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
4087bd1c925040d97927c6f6b7fe41a487c7d976efLee Jones	unsigned char buf[9];
41d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
42d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
43d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	buf[0] = (unsigned char)reg;
44d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	memcpy(&buf[1], src, bytes);
45d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
46d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = i2c_master_send(i2c, buf, bytes + 1);
47d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	if (ret < 0)
48d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		return ret;
49d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return 0;
50d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
51d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
52d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangint max8925_reg_read(struct i2c_client *i2c, int reg)
53d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
54d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	struct max8925_chip *chip = i2c_get_clientdata(i2c);
55b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	unsigned char data = 0;
56d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
57d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
58d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_lock(&chip->io_lock);
59d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = max8925_read_device(i2c, reg, 1, &data);
60d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_unlock(&chip->io_lock);
61d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
62d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	if (ret < 0)
63d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		return ret;
64d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	else
65d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		return (int)data;
66d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
67d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangEXPORT_SYMBOL(max8925_reg_read);
68d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
69d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangint max8925_reg_write(struct i2c_client *i2c, int reg,
70d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		unsigned char data)
71d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
72d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	struct max8925_chip *chip = i2c_get_clientdata(i2c);
73d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
74d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
75d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_lock(&chip->io_lock);
76d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = max8925_write_device(i2c, reg, 1, &data);
77d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_unlock(&chip->io_lock);
78d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
79d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return ret;
80d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
81d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangEXPORT_SYMBOL(max8925_reg_write);
82d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
83d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangint max8925_bulk_read(struct i2c_client *i2c, int reg,
84d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		int count, unsigned char *buf)
85d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
86d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	struct max8925_chip *chip = i2c_get_clientdata(i2c);
87d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
88d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
89d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_lock(&chip->io_lock);
90d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = max8925_read_device(i2c, reg, count, buf);
91d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_unlock(&chip->io_lock);
92d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
93d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return ret;
94d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
95d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangEXPORT_SYMBOL(max8925_bulk_read);
96d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
97d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangint max8925_bulk_write(struct i2c_client *i2c, int reg,
98d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		int count, unsigned char *buf)
99d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
100d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	struct max8925_chip *chip = i2c_get_clientdata(i2c);
101d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
102d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
103d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_lock(&chip->io_lock);
104d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = max8925_write_device(i2c, reg, count, buf);
105d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_unlock(&chip->io_lock);
106d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
107d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return ret;
108d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
109d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangEXPORT_SYMBOL(max8925_bulk_write);
110d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
111d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangint max8925_set_bits(struct i2c_client *i2c, int reg,
112d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		unsigned char mask, unsigned char data)
113d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
114d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	struct max8925_chip *chip = i2c_get_clientdata(i2c);
115d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	unsigned char value;
116d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
117d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
118d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_lock(&chip->io_lock);
119d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = max8925_read_device(i2c, reg, 1, &value);
120d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	if (ret < 0)
121d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		goto out;
122d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	value &= ~mask;
123d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	value |= data;
124d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = max8925_write_device(i2c, reg, 1, &value);
125d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangout:
126d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	mutex_unlock(&chip->io_lock);
127d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return ret;
128d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
129d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangEXPORT_SYMBOL(max8925_set_bits);
130d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
131d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
132d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangstatic const struct i2c_device_id max8925_id_table[] = {
133d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	{ "max8925", 0 },
134b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	{ },
135d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang};
136d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangMODULE_DEVICE_TABLE(i2c, max8925_id_table);
137d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
1384e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xustatic int max8925_dt_init(struct device_node *np, struct device *dev,
1394e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu			   struct max8925_platform_data *pdata)
1404e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu{
1414e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	int ret;
1424e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu
1434e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	ret = of_property_read_u32(np, "maxim,tsc-irq", &pdata->tsc_irq);
1444e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	if (ret) {
1454e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu		dev_err(dev, "Not found maxim,tsc-irq property\n");
1464e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu		return -EINVAL;
1474e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	}
1484e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	return 0;
1494e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu}
1504e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu
151f791be492f76dea7b0641ed227a60eeb2fa7e255Bill Pembertonstatic int max8925_probe(struct i2c_client *client,
152d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang				   const struct i2c_device_id *id)
153d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
154334a41ce9b753ec615e8c6c50ee07d6197190610Jingoo Han	struct max8925_platform_data *pdata = dev_get_platdata(&client->dev);
155b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	static struct max8925_chip *chip;
1564e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	struct device_node *node = client->dev.of_node;
1574e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu
1584e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	if (node && !pdata) {
1594e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu		/* parse DT to get platform data */
1604e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu		pdata = devm_kzalloc(&client->dev,
1614e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu				     sizeof(struct max8925_platform_data),
1624e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu				     GFP_KERNEL);
1634e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu		if (!pdata)
1644e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu			return -ENOMEM;
1654e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu
1664e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu		if (max8925_dt_init(node, &client->dev, pdata))
1674e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu			return -EINVAL;
1684e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	} else if (!pdata) {
169d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		pr_info("%s: platform data is missing\n", __func__);
170d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		return -EINVAL;
171d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	}
172d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
17302c7d848946d4f62ef9a2bee9de00b37e5941dc1Lee Jones	chip = devm_kzalloc(&client->dev,
17402c7d848946d4f62ef9a2bee9de00b37e5941dc1Lee Jones			    sizeof(struct max8925_chip), GFP_KERNEL);
175d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	if (chip == NULL)
176d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		return -ENOMEM;
177d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	chip->i2c = client;
178d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	chip->dev = &client->dev;
179b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	i2c_set_clientdata(client, chip);
180d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	dev_set_drvdata(chip->dev, chip);
181b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	mutex_init(&chip->io_lock);
182b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang
183b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
18496cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski	if (!chip->rtc) {
18596cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski		dev_err(chip->dev, "Failed to allocate I2C device for RTC\n");
18696cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski		return -ENODEV;
18796cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski	}
188b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	i2c_set_clientdata(chip->rtc, chip);
189b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang
190b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
19196cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski	if (!chip->adc) {
19296cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski		dev_err(chip->dev, "Failed to allocate I2C device for ADC\n");
19396cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski		i2c_unregister_device(chip->rtc);
19496cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski		return -ENODEV;
19596cf3dedc491d2f1f66cc26217f2b06b0c7b6797Krzysztof Kozlowski	}
196b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	i2c_set_clientdata(chip->adc, chip);
197b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang
198ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	device_init_wakeup(&client->dev, 1);
199ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu
200d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	max8925_device_init(chip, pdata);
201d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
202d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return 0;
203d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
204d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
2054740f73fe5388ab5d22d552d2a0dacc62418a70cBill Pembertonstatic int max8925_remove(struct i2c_client *client)
206d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
207d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	struct max8925_chip *chip = i2c_get_clientdata(client);
208d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
209d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	max8925_device_exit(chip);
210b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	i2c_unregister_device(chip->adc);
211b13c0df517bedbc40cff4ab5f797b08b1111918bHaojian Zhuang	i2c_unregister_device(chip->rtc);
212d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return 0;
213d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
214d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
215ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu#ifdef CONFIG_PM_SLEEP
216ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liustatic int max8925_suspend(struct device *dev)
217ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu{
218ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
219ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	struct max8925_chip *chip = i2c_get_clientdata(client);
220ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu
221ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	if (device_may_wakeup(dev) && chip->wakeup_flag)
222ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu		enable_irq_wake(chip->core_irq);
223ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	return 0;
224ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu}
225ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu
226ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liustatic int max8925_resume(struct device *dev)
227ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu{
228ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
229ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	struct max8925_chip *chip = i2c_get_clientdata(client);
230ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu
231ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	if (device_may_wakeup(dev) && chip->wakeup_flag)
232ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu		disable_irq_wake(chip->core_irq);
233ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu	return 0;
234ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu}
235ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu#endif
236ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu
237ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liustatic SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume);
238ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu
2394e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xustatic const struct of_device_id max8925_dt_ids[] = {
2404e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	{ .compatible = "maxim,max8925", },
2414e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu	{},
2424e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu};
2434e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing XuMODULE_DEVICE_TABLE(of, max8925_dt_ids);
2444e405ae256b7e04f7c1213136f3bfd9fb76e2023Qing Xu
245d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangstatic struct i2c_driver max8925_driver = {
246d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	.driver	= {
247d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		.name	= "max8925",
248d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		.owner	= THIS_MODULE,
249ba74e80ebaf8209cb553eb2195b26302270cfa42Kevin Liu		.pm     = &max8925_pm_ops,
25052c2c6ebfe476016db18293545244f4ed38f2572Sachin Kamat		.of_match_table = max8925_dt_ids,
251d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	},
252d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	.probe		= max8925_probe,
25384449216b01f9c2b4c9b1882f9d6abba07b7b7caBill Pemberton	.remove		= max8925_remove,
254d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	.id_table	= max8925_id_table,
255d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang};
256d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
257d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangstatic int __init max8925_i2c_init(void)
258d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
259d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	int ret;
2604ed8f7182ed4c27e7190c3533e02937bac2f9df6Lee Jones
261d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	ret = i2c_add_driver(&max8925_driver);
262d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	if (ret != 0)
263d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang		pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
2644ed8f7182ed4c27e7190c3533e02937bac2f9df6Lee Jones
265d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	return ret;
266d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
267d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangsubsys_initcall(max8925_i2c_init);
268d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
269d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangstatic void __exit max8925_i2c_exit(void)
270d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang{
271d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang	i2c_del_driver(&max8925_driver);
272d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang}
273d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuangmodule_exit(max8925_i2c_exit);
274d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian Zhuang
275d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangMODULE_DESCRIPTION("I2C Driver for Maxim 8925");
276d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangMODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
277d50f8f339f6901fccc9d4292b65ce8b69d7413d4Haojian ZhuangMODULE_LICENSE("GPL");
278