1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2004 Texas Instruments, Inc.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Some parts based tps65010.c:
6*4882a593Smuzhiyun * Copyright (C) 2004 Texas Instruments and
7*4882a593Smuzhiyun * Copyright (C) 2004-2005 David Brownell
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Some parts based on tlv320aic24.c:
10*4882a593Smuzhiyun * Copyright (C) by Kai Svahn <kai.svahn@nokia.com>
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * Changes for interrupt handling and clean-up by
13*4882a593Smuzhiyun * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
14*4882a593Smuzhiyun * Cleanup and generalized support for voltage setting by
15*4882a593Smuzhiyun * Juha Yrjola
16*4882a593Smuzhiyun * Added support for controlling VCORE and regulator sleep states,
17*4882a593Smuzhiyun * Amit Kucheria <amit.kucheria@nokia.com>
18*4882a593Smuzhiyun * Copyright (C) 2005, 2006 Nokia Corporation
19*4882a593Smuzhiyun */
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #include <linux/module.h>
22*4882a593Smuzhiyun #include <linux/i2c.h>
23*4882a593Smuzhiyun #include <linux/interrupt.h>
24*4882a593Smuzhiyun #include <linux/sched.h>
25*4882a593Smuzhiyun #include <linux/mutex.h>
26*4882a593Smuzhiyun #include <linux/workqueue.h>
27*4882a593Smuzhiyun #include <linux/delay.h>
28*4882a593Smuzhiyun #include <linux/rtc.h>
29*4882a593Smuzhiyun #include <linux/bcd.h>
30*4882a593Smuzhiyun #include <linux/slab.h>
31*4882a593Smuzhiyun #include <linux/mfd/menelaus.h>
32*4882a593Smuzhiyun #include <linux/gpio.h>
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include <asm/mach/irq.h>
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define DRIVER_NAME "menelaus"
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #define MENELAUS_I2C_ADDRESS 0x72
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #define MENELAUS_REV 0x01
42*4882a593Smuzhiyun #define MENELAUS_VCORE_CTRL1 0x02
43*4882a593Smuzhiyun #define MENELAUS_VCORE_CTRL2 0x03
44*4882a593Smuzhiyun #define MENELAUS_VCORE_CTRL3 0x04
45*4882a593Smuzhiyun #define MENELAUS_VCORE_CTRL4 0x05
46*4882a593Smuzhiyun #define MENELAUS_VCORE_CTRL5 0x06
47*4882a593Smuzhiyun #define MENELAUS_DCDC_CTRL1 0x07
48*4882a593Smuzhiyun #define MENELAUS_DCDC_CTRL2 0x08
49*4882a593Smuzhiyun #define MENELAUS_DCDC_CTRL3 0x09
50*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL1 0x0A
51*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL2 0x0B
52*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL3 0x0C
53*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL4 0x0D
54*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL5 0x0E
55*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL6 0x0F
56*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL7 0x10
57*4882a593Smuzhiyun #define MENELAUS_LDO_CTRL8 0x11
58*4882a593Smuzhiyun #define MENELAUS_SLEEP_CTRL1 0x12
59*4882a593Smuzhiyun #define MENELAUS_SLEEP_CTRL2 0x13
60*4882a593Smuzhiyun #define MENELAUS_DEVICE_OFF 0x14
61*4882a593Smuzhiyun #define MENELAUS_OSC_CTRL 0x15
62*4882a593Smuzhiyun #define MENELAUS_DETECT_CTRL 0x16
63*4882a593Smuzhiyun #define MENELAUS_INT_MASK1 0x17
64*4882a593Smuzhiyun #define MENELAUS_INT_MASK2 0x18
65*4882a593Smuzhiyun #define MENELAUS_INT_STATUS1 0x19
66*4882a593Smuzhiyun #define MENELAUS_INT_STATUS2 0x1A
67*4882a593Smuzhiyun #define MENELAUS_INT_ACK1 0x1B
68*4882a593Smuzhiyun #define MENELAUS_INT_ACK2 0x1C
69*4882a593Smuzhiyun #define MENELAUS_GPIO_CTRL 0x1D
70*4882a593Smuzhiyun #define MENELAUS_GPIO_IN 0x1E
71*4882a593Smuzhiyun #define MENELAUS_GPIO_OUT 0x1F
72*4882a593Smuzhiyun #define MENELAUS_BBSMS 0x20
73*4882a593Smuzhiyun #define MENELAUS_RTC_CTRL 0x21
74*4882a593Smuzhiyun #define MENELAUS_RTC_UPDATE 0x22
75*4882a593Smuzhiyun #define MENELAUS_RTC_SEC 0x23
76*4882a593Smuzhiyun #define MENELAUS_RTC_MIN 0x24
77*4882a593Smuzhiyun #define MENELAUS_RTC_HR 0x25
78*4882a593Smuzhiyun #define MENELAUS_RTC_DAY 0x26
79*4882a593Smuzhiyun #define MENELAUS_RTC_MON 0x27
80*4882a593Smuzhiyun #define MENELAUS_RTC_YR 0x28
81*4882a593Smuzhiyun #define MENELAUS_RTC_WKDAY 0x29
82*4882a593Smuzhiyun #define MENELAUS_RTC_AL_SEC 0x2A
83*4882a593Smuzhiyun #define MENELAUS_RTC_AL_MIN 0x2B
84*4882a593Smuzhiyun #define MENELAUS_RTC_AL_HR 0x2C
85*4882a593Smuzhiyun #define MENELAUS_RTC_AL_DAY 0x2D
86*4882a593Smuzhiyun #define MENELAUS_RTC_AL_MON 0x2E
87*4882a593Smuzhiyun #define MENELAUS_RTC_AL_YR 0x2F
88*4882a593Smuzhiyun #define MENELAUS_RTC_COMP_MSB 0x30
89*4882a593Smuzhiyun #define MENELAUS_RTC_COMP_LSB 0x31
90*4882a593Smuzhiyun #define MENELAUS_S1_PULL_EN 0x32
91*4882a593Smuzhiyun #define MENELAUS_S1_PULL_DIR 0x33
92*4882a593Smuzhiyun #define MENELAUS_S2_PULL_EN 0x34
93*4882a593Smuzhiyun #define MENELAUS_S2_PULL_DIR 0x35
94*4882a593Smuzhiyun #define MENELAUS_MCT_CTRL1 0x36
95*4882a593Smuzhiyun #define MENELAUS_MCT_CTRL2 0x37
96*4882a593Smuzhiyun #define MENELAUS_MCT_CTRL3 0x38
97*4882a593Smuzhiyun #define MENELAUS_MCT_PIN_ST 0x39
98*4882a593Smuzhiyun #define MENELAUS_DEBOUNCE1 0x3A
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun #define IH_MENELAUS_IRQS 12
101*4882a593Smuzhiyun #define MENELAUS_MMC_S1CD_IRQ 0 /* MMC slot 1 card change */
102*4882a593Smuzhiyun #define MENELAUS_MMC_S2CD_IRQ 1 /* MMC slot 2 card change */
103*4882a593Smuzhiyun #define MENELAUS_MMC_S1D1_IRQ 2 /* MMC DAT1 low in slot 1 */
104*4882a593Smuzhiyun #define MENELAUS_MMC_S2D1_IRQ 3 /* MMC DAT1 low in slot 2 */
105*4882a593Smuzhiyun #define MENELAUS_LOWBAT_IRQ 4 /* Low battery */
106*4882a593Smuzhiyun #define MENELAUS_HOTDIE_IRQ 5 /* Hot die detect */
107*4882a593Smuzhiyun #define MENELAUS_UVLO_IRQ 6 /* UVLO detect */
108*4882a593Smuzhiyun #define MENELAUS_TSHUT_IRQ 7 /* Thermal shutdown */
109*4882a593Smuzhiyun #define MENELAUS_RTCTMR_IRQ 8 /* RTC timer */
110*4882a593Smuzhiyun #define MENELAUS_RTCALM_IRQ 9 /* RTC alarm */
111*4882a593Smuzhiyun #define MENELAUS_RTCERR_IRQ 10 /* RTC error */
112*4882a593Smuzhiyun #define MENELAUS_PSHBTN_IRQ 11 /* Push button */
113*4882a593Smuzhiyun #define MENELAUS_RESERVED12_IRQ 12 /* Reserved */
114*4882a593Smuzhiyun #define MENELAUS_RESERVED13_IRQ 13 /* Reserved */
115*4882a593Smuzhiyun #define MENELAUS_RESERVED14_IRQ 14 /* Reserved */
116*4882a593Smuzhiyun #define MENELAUS_RESERVED15_IRQ 15 /* Reserved */
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /* VCORE_CTRL1 register */
119*4882a593Smuzhiyun #define VCORE_CTRL1_BYP_COMP (1 << 5)
120*4882a593Smuzhiyun #define VCORE_CTRL1_HW_NSW (1 << 7)
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /* GPIO_CTRL register */
123*4882a593Smuzhiyun #define GPIO_CTRL_SLOTSELEN (1 << 5)
124*4882a593Smuzhiyun #define GPIO_CTRL_SLPCTLEN (1 << 6)
125*4882a593Smuzhiyun #define GPIO1_DIR_INPUT (1 << 0)
126*4882a593Smuzhiyun #define GPIO2_DIR_INPUT (1 << 1)
127*4882a593Smuzhiyun #define GPIO3_DIR_INPUT (1 << 2)
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun /* MCT_CTRL1 register */
130*4882a593Smuzhiyun #define MCT_CTRL1_S1_CMD_OD (1 << 2)
131*4882a593Smuzhiyun #define MCT_CTRL1_S2_CMD_OD (1 << 3)
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun /* MCT_CTRL2 register */
134*4882a593Smuzhiyun #define MCT_CTRL2_VS2_SEL_D0 (1 << 0)
135*4882a593Smuzhiyun #define MCT_CTRL2_VS2_SEL_D1 (1 << 1)
136*4882a593Smuzhiyun #define MCT_CTRL2_S1CD_BUFEN (1 << 4)
137*4882a593Smuzhiyun #define MCT_CTRL2_S2CD_BUFEN (1 << 5)
138*4882a593Smuzhiyun #define MCT_CTRL2_S1CD_DBEN (1 << 6)
139*4882a593Smuzhiyun #define MCT_CTRL2_S2CD_BEN (1 << 7)
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun /* MCT_CTRL3 register */
142*4882a593Smuzhiyun #define MCT_CTRL3_SLOT1_EN (1 << 0)
143*4882a593Smuzhiyun #define MCT_CTRL3_SLOT2_EN (1 << 1)
144*4882a593Smuzhiyun #define MCT_CTRL3_S1_AUTO_EN (1 << 2)
145*4882a593Smuzhiyun #define MCT_CTRL3_S2_AUTO_EN (1 << 3)
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun /* MCT_PIN_ST register */
148*4882a593Smuzhiyun #define MCT_PIN_ST_S1_CD_ST (1 << 0)
149*4882a593Smuzhiyun #define MCT_PIN_ST_S2_CD_ST (1 << 1)
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun static void menelaus_work(struct work_struct *_menelaus);
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun struct menelaus_chip {
154*4882a593Smuzhiyun struct mutex lock;
155*4882a593Smuzhiyun struct i2c_client *client;
156*4882a593Smuzhiyun struct work_struct work;
157*4882a593Smuzhiyun #ifdef CONFIG_RTC_DRV_TWL92330
158*4882a593Smuzhiyun struct rtc_device *rtc;
159*4882a593Smuzhiyun u8 rtc_control;
160*4882a593Smuzhiyun unsigned uie:1;
161*4882a593Smuzhiyun #endif
162*4882a593Smuzhiyun unsigned vcore_hw_mode:1;
163*4882a593Smuzhiyun u8 mask1, mask2;
164*4882a593Smuzhiyun void (*handlers[16])(struct menelaus_chip *);
165*4882a593Smuzhiyun void (*mmc_callback)(void *data, u8 mask);
166*4882a593Smuzhiyun void *mmc_callback_data;
167*4882a593Smuzhiyun };
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun static struct menelaus_chip *the_menelaus;
170*4882a593Smuzhiyun
menelaus_write_reg(int reg,u8 value)171*4882a593Smuzhiyun static int menelaus_write_reg(int reg, u8 value)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun if (val < 0) {
176*4882a593Smuzhiyun pr_err(DRIVER_NAME ": write error");
177*4882a593Smuzhiyun return val;
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun return 0;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
menelaus_read_reg(int reg)183*4882a593Smuzhiyun static int menelaus_read_reg(int reg)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun if (val < 0)
188*4882a593Smuzhiyun pr_err(DRIVER_NAME ": read error");
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun return val;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
menelaus_enable_irq(int irq)193*4882a593Smuzhiyun static int menelaus_enable_irq(int irq)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun if (irq > 7) {
196*4882a593Smuzhiyun irq -= 8;
197*4882a593Smuzhiyun the_menelaus->mask2 &= ~(1 << irq);
198*4882a593Smuzhiyun return menelaus_write_reg(MENELAUS_INT_MASK2,
199*4882a593Smuzhiyun the_menelaus->mask2);
200*4882a593Smuzhiyun } else {
201*4882a593Smuzhiyun the_menelaus->mask1 &= ~(1 << irq);
202*4882a593Smuzhiyun return menelaus_write_reg(MENELAUS_INT_MASK1,
203*4882a593Smuzhiyun the_menelaus->mask1);
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun
menelaus_disable_irq(int irq)207*4882a593Smuzhiyun static int menelaus_disable_irq(int irq)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun if (irq > 7) {
210*4882a593Smuzhiyun irq -= 8;
211*4882a593Smuzhiyun the_menelaus->mask2 |= (1 << irq);
212*4882a593Smuzhiyun return menelaus_write_reg(MENELAUS_INT_MASK2,
213*4882a593Smuzhiyun the_menelaus->mask2);
214*4882a593Smuzhiyun } else {
215*4882a593Smuzhiyun the_menelaus->mask1 |= (1 << irq);
216*4882a593Smuzhiyun return menelaus_write_reg(MENELAUS_INT_MASK1,
217*4882a593Smuzhiyun the_menelaus->mask1);
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
menelaus_ack_irq(int irq)221*4882a593Smuzhiyun static int menelaus_ack_irq(int irq)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun if (irq > 7)
224*4882a593Smuzhiyun return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
225*4882a593Smuzhiyun else
226*4882a593Smuzhiyun return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun /* Adds a handler for an interrupt. Does not run in interrupt context */
menelaus_add_irq_work(int irq,void (* handler)(struct menelaus_chip *))230*4882a593Smuzhiyun static int menelaus_add_irq_work(int irq,
231*4882a593Smuzhiyun void (*handler)(struct menelaus_chip *))
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun int ret = 0;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
236*4882a593Smuzhiyun the_menelaus->handlers[irq] = handler;
237*4882a593Smuzhiyun ret = menelaus_enable_irq(irq);
238*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun return ret;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun /* Removes handler for an interrupt */
menelaus_remove_irq_work(int irq)244*4882a593Smuzhiyun static int menelaus_remove_irq_work(int irq)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun int ret = 0;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
249*4882a593Smuzhiyun ret = menelaus_disable_irq(irq);
250*4882a593Smuzhiyun the_menelaus->handlers[irq] = NULL;
251*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun return ret;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun /*
257*4882a593Smuzhiyun * Gets scheduled when a card detect interrupt happens. Note that in some cases
258*4882a593Smuzhiyun * this line is wired to card cover switch rather than the card detect switch
259*4882a593Smuzhiyun * in each slot. In this case the cards are not seen by menelaus.
260*4882a593Smuzhiyun * FIXME: Add handling for D1 too
261*4882a593Smuzhiyun */
menelaus_mmc_cd_work(struct menelaus_chip * menelaus_hw)262*4882a593Smuzhiyun static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun int reg;
265*4882a593Smuzhiyun unsigned char card_mask = 0;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun reg = menelaus_read_reg(MENELAUS_MCT_PIN_ST);
268*4882a593Smuzhiyun if (reg < 0)
269*4882a593Smuzhiyun return;
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun if (!(reg & 0x1))
272*4882a593Smuzhiyun card_mask |= MCT_PIN_ST_S1_CD_ST;
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun if (!(reg & 0x2))
275*4882a593Smuzhiyun card_mask |= MCT_PIN_ST_S2_CD_ST;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun if (menelaus_hw->mmc_callback)
278*4882a593Smuzhiyun menelaus_hw->mmc_callback(menelaus_hw->mmc_callback_data,
279*4882a593Smuzhiyun card_mask);
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun /*
283*4882a593Smuzhiyun * Toggles the MMC slots between open-drain and push-pull mode.
284*4882a593Smuzhiyun */
menelaus_set_mmc_opendrain(int slot,int enable)285*4882a593Smuzhiyun int menelaus_set_mmc_opendrain(int slot, int enable)
286*4882a593Smuzhiyun {
287*4882a593Smuzhiyun int ret, val;
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun if (slot != 1 && slot != 2)
290*4882a593Smuzhiyun return -EINVAL;
291*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
292*4882a593Smuzhiyun ret = menelaus_read_reg(MENELAUS_MCT_CTRL1);
293*4882a593Smuzhiyun if (ret < 0) {
294*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
295*4882a593Smuzhiyun return ret;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun val = ret;
298*4882a593Smuzhiyun if (slot == 1) {
299*4882a593Smuzhiyun if (enable)
300*4882a593Smuzhiyun val |= MCT_CTRL1_S1_CMD_OD;
301*4882a593Smuzhiyun else
302*4882a593Smuzhiyun val &= ~MCT_CTRL1_S1_CMD_OD;
303*4882a593Smuzhiyun } else {
304*4882a593Smuzhiyun if (enable)
305*4882a593Smuzhiyun val |= MCT_CTRL1_S2_CMD_OD;
306*4882a593Smuzhiyun else
307*4882a593Smuzhiyun val &= ~MCT_CTRL1_S2_CMD_OD;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_MCT_CTRL1, val);
310*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun return ret;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_set_mmc_opendrain);
315*4882a593Smuzhiyun
menelaus_set_slot_sel(int enable)316*4882a593Smuzhiyun int menelaus_set_slot_sel(int enable)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun int ret;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
321*4882a593Smuzhiyun ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
322*4882a593Smuzhiyun if (ret < 0)
323*4882a593Smuzhiyun goto out;
324*4882a593Smuzhiyun ret |= GPIO2_DIR_INPUT;
325*4882a593Smuzhiyun if (enable)
326*4882a593Smuzhiyun ret |= GPIO_CTRL_SLOTSELEN;
327*4882a593Smuzhiyun else
328*4882a593Smuzhiyun ret &= ~GPIO_CTRL_SLOTSELEN;
329*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
330*4882a593Smuzhiyun out:
331*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
332*4882a593Smuzhiyun return ret;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_set_slot_sel);
335*4882a593Smuzhiyun
menelaus_set_mmc_slot(int slot,int enable,int power,int cd_en)336*4882a593Smuzhiyun int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun int ret, val;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun if (slot != 1 && slot != 2)
341*4882a593Smuzhiyun return -EINVAL;
342*4882a593Smuzhiyun if (power >= 3)
343*4882a593Smuzhiyun return -EINVAL;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun ret = menelaus_read_reg(MENELAUS_MCT_CTRL2);
348*4882a593Smuzhiyun if (ret < 0)
349*4882a593Smuzhiyun goto out;
350*4882a593Smuzhiyun val = ret;
351*4882a593Smuzhiyun if (slot == 1) {
352*4882a593Smuzhiyun if (cd_en)
353*4882a593Smuzhiyun val |= MCT_CTRL2_S1CD_BUFEN | MCT_CTRL2_S1CD_DBEN;
354*4882a593Smuzhiyun else
355*4882a593Smuzhiyun val &= ~(MCT_CTRL2_S1CD_BUFEN | MCT_CTRL2_S1CD_DBEN);
356*4882a593Smuzhiyun } else {
357*4882a593Smuzhiyun if (cd_en)
358*4882a593Smuzhiyun val |= MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN;
359*4882a593Smuzhiyun else
360*4882a593Smuzhiyun val &= ~(MCT_CTRL2_S2CD_BUFEN | MCT_CTRL2_S2CD_BEN);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, val);
363*4882a593Smuzhiyun if (ret < 0)
364*4882a593Smuzhiyun goto out;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun ret = menelaus_read_reg(MENELAUS_MCT_CTRL3);
367*4882a593Smuzhiyun if (ret < 0)
368*4882a593Smuzhiyun goto out;
369*4882a593Smuzhiyun val = ret;
370*4882a593Smuzhiyun if (slot == 1) {
371*4882a593Smuzhiyun if (enable)
372*4882a593Smuzhiyun val |= MCT_CTRL3_SLOT1_EN;
373*4882a593Smuzhiyun else
374*4882a593Smuzhiyun val &= ~MCT_CTRL3_SLOT1_EN;
375*4882a593Smuzhiyun } else {
376*4882a593Smuzhiyun int b;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun if (enable)
379*4882a593Smuzhiyun val |= MCT_CTRL3_SLOT2_EN;
380*4882a593Smuzhiyun else
381*4882a593Smuzhiyun val &= ~MCT_CTRL3_SLOT2_EN;
382*4882a593Smuzhiyun b = menelaus_read_reg(MENELAUS_MCT_CTRL2);
383*4882a593Smuzhiyun b &= ~(MCT_CTRL2_VS2_SEL_D0 | MCT_CTRL2_VS2_SEL_D1);
384*4882a593Smuzhiyun b |= power;
385*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, b);
386*4882a593Smuzhiyun if (ret < 0)
387*4882a593Smuzhiyun goto out;
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun /* Disable autonomous shutdown */
390*4882a593Smuzhiyun val &= ~(MCT_CTRL3_S1_AUTO_EN | MCT_CTRL3_S2_AUTO_EN);
391*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_MCT_CTRL3, val);
392*4882a593Smuzhiyun out:
393*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
394*4882a593Smuzhiyun return ret;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_set_mmc_slot);
397*4882a593Smuzhiyun
menelaus_register_mmc_callback(void (* callback)(void * data,u8 card_mask),void * data)398*4882a593Smuzhiyun int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
399*4882a593Smuzhiyun void *data)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun int ret = 0;
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun the_menelaus->mmc_callback_data = data;
404*4882a593Smuzhiyun the_menelaus->mmc_callback = callback;
405*4882a593Smuzhiyun ret = menelaus_add_irq_work(MENELAUS_MMC_S1CD_IRQ,
406*4882a593Smuzhiyun menelaus_mmc_cd_work);
407*4882a593Smuzhiyun if (ret < 0)
408*4882a593Smuzhiyun return ret;
409*4882a593Smuzhiyun ret = menelaus_add_irq_work(MENELAUS_MMC_S2CD_IRQ,
410*4882a593Smuzhiyun menelaus_mmc_cd_work);
411*4882a593Smuzhiyun if (ret < 0)
412*4882a593Smuzhiyun return ret;
413*4882a593Smuzhiyun ret = menelaus_add_irq_work(MENELAUS_MMC_S1D1_IRQ,
414*4882a593Smuzhiyun menelaus_mmc_cd_work);
415*4882a593Smuzhiyun if (ret < 0)
416*4882a593Smuzhiyun return ret;
417*4882a593Smuzhiyun ret = menelaus_add_irq_work(MENELAUS_MMC_S2D1_IRQ,
418*4882a593Smuzhiyun menelaus_mmc_cd_work);
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun return ret;
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_register_mmc_callback);
423*4882a593Smuzhiyun
menelaus_unregister_mmc_callback(void)424*4882a593Smuzhiyun void menelaus_unregister_mmc_callback(void)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun menelaus_remove_irq_work(MENELAUS_MMC_S1CD_IRQ);
427*4882a593Smuzhiyun menelaus_remove_irq_work(MENELAUS_MMC_S2CD_IRQ);
428*4882a593Smuzhiyun menelaus_remove_irq_work(MENELAUS_MMC_S1D1_IRQ);
429*4882a593Smuzhiyun menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun the_menelaus->mmc_callback = NULL;
432*4882a593Smuzhiyun the_menelaus->mmc_callback_data = NULL;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun struct menelaus_vtg {
437*4882a593Smuzhiyun const char *name;
438*4882a593Smuzhiyun u8 vtg_reg;
439*4882a593Smuzhiyun u8 vtg_shift;
440*4882a593Smuzhiyun u8 vtg_bits;
441*4882a593Smuzhiyun u8 mode_reg;
442*4882a593Smuzhiyun };
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun struct menelaus_vtg_value {
445*4882a593Smuzhiyun u16 vtg;
446*4882a593Smuzhiyun u16 val;
447*4882a593Smuzhiyun };
448*4882a593Smuzhiyun
menelaus_set_voltage(const struct menelaus_vtg * vtg,int mV,int vtg_val,int mode)449*4882a593Smuzhiyun static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
450*4882a593Smuzhiyun int vtg_val, int mode)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun int val, ret;
453*4882a593Smuzhiyun struct i2c_client *c = the_menelaus->client;
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun ret = menelaus_read_reg(vtg->vtg_reg);
458*4882a593Smuzhiyun if (ret < 0)
459*4882a593Smuzhiyun goto out;
460*4882a593Smuzhiyun val = ret & ~(((1 << vtg->vtg_bits) - 1) << vtg->vtg_shift);
461*4882a593Smuzhiyun val |= vtg_val << vtg->vtg_shift;
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun dev_dbg(&c->dev, "Setting voltage '%s'"
464*4882a593Smuzhiyun "to %d mV (reg 0x%02x, val 0x%02x)\n",
465*4882a593Smuzhiyun vtg->name, mV, vtg->vtg_reg, val);
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun ret = menelaus_write_reg(vtg->vtg_reg, val);
468*4882a593Smuzhiyun if (ret < 0)
469*4882a593Smuzhiyun goto out;
470*4882a593Smuzhiyun ret = menelaus_write_reg(vtg->mode_reg, mode);
471*4882a593Smuzhiyun out:
472*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
473*4882a593Smuzhiyun if (ret == 0) {
474*4882a593Smuzhiyun /* Wait for voltage to stabilize */
475*4882a593Smuzhiyun msleep(1);
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun return ret;
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
menelaus_get_vtg_value(int vtg,const struct menelaus_vtg_value * tbl,int n)480*4882a593Smuzhiyun static int menelaus_get_vtg_value(int vtg, const struct menelaus_vtg_value *tbl,
481*4882a593Smuzhiyun int n)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun int i;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun for (i = 0; i < n; i++, tbl++)
486*4882a593Smuzhiyun if (tbl->vtg == vtg)
487*4882a593Smuzhiyun return tbl->val;
488*4882a593Smuzhiyun return -EINVAL;
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun /*
492*4882a593Smuzhiyun * Vcore can be programmed in two ways:
493*4882a593Smuzhiyun * SW-controlled: Required voltage is programmed into VCORE_CTRL1
494*4882a593Smuzhiyun * HW-controlled: Required range (roof-floor) is programmed into VCORE_CTRL3
495*4882a593Smuzhiyun * and VCORE_CTRL4
496*4882a593Smuzhiyun *
497*4882a593Smuzhiyun * Call correct 'set' function accordingly
498*4882a593Smuzhiyun */
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun static const struct menelaus_vtg_value vcore_values[] = {
501*4882a593Smuzhiyun { 1000, 0 },
502*4882a593Smuzhiyun { 1025, 1 },
503*4882a593Smuzhiyun { 1050, 2 },
504*4882a593Smuzhiyun { 1075, 3 },
505*4882a593Smuzhiyun { 1100, 4 },
506*4882a593Smuzhiyun { 1125, 5 },
507*4882a593Smuzhiyun { 1150, 6 },
508*4882a593Smuzhiyun { 1175, 7 },
509*4882a593Smuzhiyun { 1200, 8 },
510*4882a593Smuzhiyun { 1225, 9 },
511*4882a593Smuzhiyun { 1250, 10 },
512*4882a593Smuzhiyun { 1275, 11 },
513*4882a593Smuzhiyun { 1300, 12 },
514*4882a593Smuzhiyun { 1325, 13 },
515*4882a593Smuzhiyun { 1350, 14 },
516*4882a593Smuzhiyun { 1375, 15 },
517*4882a593Smuzhiyun { 1400, 16 },
518*4882a593Smuzhiyun { 1425, 17 },
519*4882a593Smuzhiyun { 1450, 18 },
520*4882a593Smuzhiyun };
521*4882a593Smuzhiyun
menelaus_set_vcore_hw(unsigned int roof_mV,unsigned int floor_mV)522*4882a593Smuzhiyun int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun int fval, rval, val, ret;
525*4882a593Smuzhiyun struct i2c_client *c = the_menelaus->client;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun rval = menelaus_get_vtg_value(roof_mV, vcore_values,
528*4882a593Smuzhiyun ARRAY_SIZE(vcore_values));
529*4882a593Smuzhiyun if (rval < 0)
530*4882a593Smuzhiyun return -EINVAL;
531*4882a593Smuzhiyun fval = menelaus_get_vtg_value(floor_mV, vcore_values,
532*4882a593Smuzhiyun ARRAY_SIZE(vcore_values));
533*4882a593Smuzhiyun if (fval < 0)
534*4882a593Smuzhiyun return -EINVAL;
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun dev_dbg(&c->dev, "Setting VCORE FLOOR to %d mV and ROOF to %d mV\n",
537*4882a593Smuzhiyun floor_mV, roof_mV);
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
540*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_VCORE_CTRL3, fval);
541*4882a593Smuzhiyun if (ret < 0)
542*4882a593Smuzhiyun goto out;
543*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_VCORE_CTRL4, rval);
544*4882a593Smuzhiyun if (ret < 0)
545*4882a593Smuzhiyun goto out;
546*4882a593Smuzhiyun if (!the_menelaus->vcore_hw_mode) {
547*4882a593Smuzhiyun val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
548*4882a593Smuzhiyun /* HW mode, turn OFF byte comparator */
549*4882a593Smuzhiyun val |= (VCORE_CTRL1_HW_NSW | VCORE_CTRL1_BYP_COMP);
550*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
551*4882a593Smuzhiyun the_menelaus->vcore_hw_mode = 1;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun msleep(1);
554*4882a593Smuzhiyun out:
555*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
556*4882a593Smuzhiyun return ret;
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun static const struct menelaus_vtg vmem_vtg = {
560*4882a593Smuzhiyun .name = "VMEM",
561*4882a593Smuzhiyun .vtg_reg = MENELAUS_LDO_CTRL1,
562*4882a593Smuzhiyun .vtg_shift = 0,
563*4882a593Smuzhiyun .vtg_bits = 2,
564*4882a593Smuzhiyun .mode_reg = MENELAUS_LDO_CTRL3,
565*4882a593Smuzhiyun };
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun static const struct menelaus_vtg_value vmem_values[] = {
568*4882a593Smuzhiyun { 1500, 0 },
569*4882a593Smuzhiyun { 1800, 1 },
570*4882a593Smuzhiyun { 1900, 2 },
571*4882a593Smuzhiyun { 2500, 3 },
572*4882a593Smuzhiyun };
573*4882a593Smuzhiyun
menelaus_set_vmem(unsigned int mV)574*4882a593Smuzhiyun int menelaus_set_vmem(unsigned int mV)
575*4882a593Smuzhiyun {
576*4882a593Smuzhiyun int val;
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun if (mV == 0)
579*4882a593Smuzhiyun return menelaus_set_voltage(&vmem_vtg, 0, 0, 0);
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun val = menelaus_get_vtg_value(mV, vmem_values, ARRAY_SIZE(vmem_values));
582*4882a593Smuzhiyun if (val < 0)
583*4882a593Smuzhiyun return -EINVAL;
584*4882a593Smuzhiyun return menelaus_set_voltage(&vmem_vtg, mV, val, 0x02);
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_set_vmem);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun static const struct menelaus_vtg vio_vtg = {
589*4882a593Smuzhiyun .name = "VIO",
590*4882a593Smuzhiyun .vtg_reg = MENELAUS_LDO_CTRL1,
591*4882a593Smuzhiyun .vtg_shift = 2,
592*4882a593Smuzhiyun .vtg_bits = 2,
593*4882a593Smuzhiyun .mode_reg = MENELAUS_LDO_CTRL4,
594*4882a593Smuzhiyun };
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun static const struct menelaus_vtg_value vio_values[] = {
597*4882a593Smuzhiyun { 1500, 0 },
598*4882a593Smuzhiyun { 1800, 1 },
599*4882a593Smuzhiyun { 2500, 2 },
600*4882a593Smuzhiyun { 2800, 3 },
601*4882a593Smuzhiyun };
602*4882a593Smuzhiyun
menelaus_set_vio(unsigned int mV)603*4882a593Smuzhiyun int menelaus_set_vio(unsigned int mV)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun int val;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun if (mV == 0)
608*4882a593Smuzhiyun return menelaus_set_voltage(&vio_vtg, 0, 0, 0);
609*4882a593Smuzhiyun
610*4882a593Smuzhiyun val = menelaus_get_vtg_value(mV, vio_values, ARRAY_SIZE(vio_values));
611*4882a593Smuzhiyun if (val < 0)
612*4882a593Smuzhiyun return -EINVAL;
613*4882a593Smuzhiyun return menelaus_set_voltage(&vio_vtg, mV, val, 0x02);
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_set_vio);
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun static const struct menelaus_vtg_value vdcdc_values[] = {
618*4882a593Smuzhiyun { 1500, 0 },
619*4882a593Smuzhiyun { 1800, 1 },
620*4882a593Smuzhiyun { 2000, 2 },
621*4882a593Smuzhiyun { 2200, 3 },
622*4882a593Smuzhiyun { 2400, 4 },
623*4882a593Smuzhiyun { 2800, 5 },
624*4882a593Smuzhiyun { 3000, 6 },
625*4882a593Smuzhiyun { 3300, 7 },
626*4882a593Smuzhiyun };
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun static const struct menelaus_vtg vdcdc2_vtg = {
629*4882a593Smuzhiyun .name = "VDCDC2",
630*4882a593Smuzhiyun .vtg_reg = MENELAUS_DCDC_CTRL1,
631*4882a593Smuzhiyun .vtg_shift = 0,
632*4882a593Smuzhiyun .vtg_bits = 3,
633*4882a593Smuzhiyun .mode_reg = MENELAUS_DCDC_CTRL2,
634*4882a593Smuzhiyun };
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun static const struct menelaus_vtg vdcdc3_vtg = {
637*4882a593Smuzhiyun .name = "VDCDC3",
638*4882a593Smuzhiyun .vtg_reg = MENELAUS_DCDC_CTRL1,
639*4882a593Smuzhiyun .vtg_shift = 3,
640*4882a593Smuzhiyun .vtg_bits = 3,
641*4882a593Smuzhiyun .mode_reg = MENELAUS_DCDC_CTRL3,
642*4882a593Smuzhiyun };
643*4882a593Smuzhiyun
menelaus_set_vdcdc(int dcdc,unsigned int mV)644*4882a593Smuzhiyun int menelaus_set_vdcdc(int dcdc, unsigned int mV)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun const struct menelaus_vtg *vtg;
647*4882a593Smuzhiyun int val;
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun if (dcdc != 2 && dcdc != 3)
650*4882a593Smuzhiyun return -EINVAL;
651*4882a593Smuzhiyun if (dcdc == 2)
652*4882a593Smuzhiyun vtg = &vdcdc2_vtg;
653*4882a593Smuzhiyun else
654*4882a593Smuzhiyun vtg = &vdcdc3_vtg;
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun if (mV == 0)
657*4882a593Smuzhiyun return menelaus_set_voltage(vtg, 0, 0, 0);
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun val = menelaus_get_vtg_value(mV, vdcdc_values,
660*4882a593Smuzhiyun ARRAY_SIZE(vdcdc_values));
661*4882a593Smuzhiyun if (val < 0)
662*4882a593Smuzhiyun return -EINVAL;
663*4882a593Smuzhiyun return menelaus_set_voltage(vtg, mV, val, 0x03);
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun static const struct menelaus_vtg_value vmmc_values[] = {
667*4882a593Smuzhiyun { 1850, 0 },
668*4882a593Smuzhiyun { 2800, 1 },
669*4882a593Smuzhiyun { 3000, 2 },
670*4882a593Smuzhiyun { 3100, 3 },
671*4882a593Smuzhiyun };
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun static const struct menelaus_vtg vmmc_vtg = {
674*4882a593Smuzhiyun .name = "VMMC",
675*4882a593Smuzhiyun .vtg_reg = MENELAUS_LDO_CTRL1,
676*4882a593Smuzhiyun .vtg_shift = 6,
677*4882a593Smuzhiyun .vtg_bits = 2,
678*4882a593Smuzhiyun .mode_reg = MENELAUS_LDO_CTRL7,
679*4882a593Smuzhiyun };
680*4882a593Smuzhiyun
menelaus_set_vmmc(unsigned int mV)681*4882a593Smuzhiyun int menelaus_set_vmmc(unsigned int mV)
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun int val;
684*4882a593Smuzhiyun
685*4882a593Smuzhiyun if (mV == 0)
686*4882a593Smuzhiyun return menelaus_set_voltage(&vmmc_vtg, 0, 0, 0);
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun val = menelaus_get_vtg_value(mV, vmmc_values, ARRAY_SIZE(vmmc_values));
689*4882a593Smuzhiyun if (val < 0)
690*4882a593Smuzhiyun return -EINVAL;
691*4882a593Smuzhiyun return menelaus_set_voltage(&vmmc_vtg, mV, val, 0x02);
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_set_vmmc);
694*4882a593Smuzhiyun
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun static const struct menelaus_vtg_value vaux_values[] = {
697*4882a593Smuzhiyun { 1500, 0 },
698*4882a593Smuzhiyun { 1800, 1 },
699*4882a593Smuzhiyun { 2500, 2 },
700*4882a593Smuzhiyun { 2800, 3 },
701*4882a593Smuzhiyun };
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun static const struct menelaus_vtg vaux_vtg = {
704*4882a593Smuzhiyun .name = "VAUX",
705*4882a593Smuzhiyun .vtg_reg = MENELAUS_LDO_CTRL1,
706*4882a593Smuzhiyun .vtg_shift = 4,
707*4882a593Smuzhiyun .vtg_bits = 2,
708*4882a593Smuzhiyun .mode_reg = MENELAUS_LDO_CTRL6,
709*4882a593Smuzhiyun };
710*4882a593Smuzhiyun
menelaus_set_vaux(unsigned int mV)711*4882a593Smuzhiyun int menelaus_set_vaux(unsigned int mV)
712*4882a593Smuzhiyun {
713*4882a593Smuzhiyun int val;
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun if (mV == 0)
716*4882a593Smuzhiyun return menelaus_set_voltage(&vaux_vtg, 0, 0, 0);
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun val = menelaus_get_vtg_value(mV, vaux_values, ARRAY_SIZE(vaux_values));
719*4882a593Smuzhiyun if (val < 0)
720*4882a593Smuzhiyun return -EINVAL;
721*4882a593Smuzhiyun return menelaus_set_voltage(&vaux_vtg, mV, val, 0x02);
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_set_vaux);
724*4882a593Smuzhiyun
menelaus_get_slot_pin_states(void)725*4882a593Smuzhiyun int menelaus_get_slot_pin_states(void)
726*4882a593Smuzhiyun {
727*4882a593Smuzhiyun return menelaus_read_reg(MENELAUS_MCT_PIN_ST);
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun EXPORT_SYMBOL(menelaus_get_slot_pin_states);
730*4882a593Smuzhiyun
menelaus_set_regulator_sleep(int enable,u32 val)731*4882a593Smuzhiyun int menelaus_set_regulator_sleep(int enable, u32 val)
732*4882a593Smuzhiyun {
733*4882a593Smuzhiyun int t, ret;
734*4882a593Smuzhiyun struct i2c_client *c = the_menelaus->client;
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun mutex_lock(&the_menelaus->lock);
737*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_SLEEP_CTRL2, val);
738*4882a593Smuzhiyun if (ret < 0)
739*4882a593Smuzhiyun goto out;
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun dev_dbg(&c->dev, "regulator sleep configuration: %02x\n", val);
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
744*4882a593Smuzhiyun if (ret < 0)
745*4882a593Smuzhiyun goto out;
746*4882a593Smuzhiyun t = (GPIO_CTRL_SLPCTLEN | GPIO3_DIR_INPUT);
747*4882a593Smuzhiyun if (enable)
748*4882a593Smuzhiyun ret |= t;
749*4882a593Smuzhiyun else
750*4882a593Smuzhiyun ret &= ~t;
751*4882a593Smuzhiyun ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
752*4882a593Smuzhiyun out:
753*4882a593Smuzhiyun mutex_unlock(&the_menelaus->lock);
754*4882a593Smuzhiyun return ret;
755*4882a593Smuzhiyun }
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun /*-----------------------------------------------------------------------*/
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun /* Handles Menelaus interrupts. Does not run in interrupt context */
menelaus_work(struct work_struct * _menelaus)760*4882a593Smuzhiyun static void menelaus_work(struct work_struct *_menelaus)
761*4882a593Smuzhiyun {
762*4882a593Smuzhiyun struct menelaus_chip *menelaus =
763*4882a593Smuzhiyun container_of(_menelaus, struct menelaus_chip, work);
764*4882a593Smuzhiyun void (*handler)(struct menelaus_chip *menelaus);
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun while (1) {
767*4882a593Smuzhiyun unsigned isr;
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
770*4882a593Smuzhiyun & ~menelaus->mask2) << 8;
771*4882a593Smuzhiyun isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
772*4882a593Smuzhiyun & ~menelaus->mask1;
773*4882a593Smuzhiyun if (!isr)
774*4882a593Smuzhiyun break;
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun while (isr) {
777*4882a593Smuzhiyun int irq = fls(isr) - 1;
778*4882a593Smuzhiyun isr &= ~(1 << irq);
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun mutex_lock(&menelaus->lock);
781*4882a593Smuzhiyun menelaus_disable_irq(irq);
782*4882a593Smuzhiyun menelaus_ack_irq(irq);
783*4882a593Smuzhiyun handler = menelaus->handlers[irq];
784*4882a593Smuzhiyun if (handler)
785*4882a593Smuzhiyun handler(menelaus);
786*4882a593Smuzhiyun menelaus_enable_irq(irq);
787*4882a593Smuzhiyun mutex_unlock(&menelaus->lock);
788*4882a593Smuzhiyun }
789*4882a593Smuzhiyun }
790*4882a593Smuzhiyun enable_irq(menelaus->client->irq);
791*4882a593Smuzhiyun }
792*4882a593Smuzhiyun
793*4882a593Smuzhiyun /*
794*4882a593Smuzhiyun * We cannot use I2C in interrupt context, so we just schedule work.
795*4882a593Smuzhiyun */
menelaus_irq(int irq,void * _menelaus)796*4882a593Smuzhiyun static irqreturn_t menelaus_irq(int irq, void *_menelaus)
797*4882a593Smuzhiyun {
798*4882a593Smuzhiyun struct menelaus_chip *menelaus = _menelaus;
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun disable_irq_nosync(irq);
801*4882a593Smuzhiyun (void)schedule_work(&menelaus->work);
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun return IRQ_HANDLED;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun /*-----------------------------------------------------------------------*/
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun /*
809*4882a593Smuzhiyun * The RTC needs to be set once, then it runs on backup battery power.
810*4882a593Smuzhiyun * It supports alarms, including system wake alarms (from some modes);
811*4882a593Smuzhiyun * and 1/second IRQs if requested.
812*4882a593Smuzhiyun */
813*4882a593Smuzhiyun #ifdef CONFIG_RTC_DRV_TWL92330
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun #define RTC_CTRL_RTC_EN (1 << 0)
816*4882a593Smuzhiyun #define RTC_CTRL_AL_EN (1 << 1)
817*4882a593Smuzhiyun #define RTC_CTRL_MODE12 (1 << 2)
818*4882a593Smuzhiyun #define RTC_CTRL_EVERY_MASK (3 << 3)
819*4882a593Smuzhiyun #define RTC_CTRL_EVERY_SEC (0 << 3)
820*4882a593Smuzhiyun #define RTC_CTRL_EVERY_MIN (1 << 3)
821*4882a593Smuzhiyun #define RTC_CTRL_EVERY_HR (2 << 3)
822*4882a593Smuzhiyun #define RTC_CTRL_EVERY_DAY (3 << 3)
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun #define RTC_UPDATE_EVERY 0x08
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun #define RTC_HR_PM (1 << 7)
827*4882a593Smuzhiyun
menelaus_to_time(char * regs,struct rtc_time * t)828*4882a593Smuzhiyun static void menelaus_to_time(char *regs, struct rtc_time *t)
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun t->tm_sec = bcd2bin(regs[0]);
831*4882a593Smuzhiyun t->tm_min = bcd2bin(regs[1]);
832*4882a593Smuzhiyun if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
833*4882a593Smuzhiyun t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1;
834*4882a593Smuzhiyun if (regs[2] & RTC_HR_PM)
835*4882a593Smuzhiyun t->tm_hour += 12;
836*4882a593Smuzhiyun } else
837*4882a593Smuzhiyun t->tm_hour = bcd2bin(regs[2] & 0x3f);
838*4882a593Smuzhiyun t->tm_mday = bcd2bin(regs[3]);
839*4882a593Smuzhiyun t->tm_mon = bcd2bin(regs[4]) - 1;
840*4882a593Smuzhiyun t->tm_year = bcd2bin(regs[5]) + 100;
841*4882a593Smuzhiyun }
842*4882a593Smuzhiyun
time_to_menelaus(struct rtc_time * t,int regnum)843*4882a593Smuzhiyun static int time_to_menelaus(struct rtc_time *t, int regnum)
844*4882a593Smuzhiyun {
845*4882a593Smuzhiyun int hour, status;
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec));
848*4882a593Smuzhiyun if (status < 0)
849*4882a593Smuzhiyun goto fail;
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min));
852*4882a593Smuzhiyun if (status < 0)
853*4882a593Smuzhiyun goto fail;
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
856*4882a593Smuzhiyun hour = t->tm_hour + 1;
857*4882a593Smuzhiyun if (hour > 12)
858*4882a593Smuzhiyun hour = RTC_HR_PM | bin2bcd(hour - 12);
859*4882a593Smuzhiyun else
860*4882a593Smuzhiyun hour = bin2bcd(hour);
861*4882a593Smuzhiyun } else
862*4882a593Smuzhiyun hour = bin2bcd(t->tm_hour);
863*4882a593Smuzhiyun status = menelaus_write_reg(regnum++, hour);
864*4882a593Smuzhiyun if (status < 0)
865*4882a593Smuzhiyun goto fail;
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday));
868*4882a593Smuzhiyun if (status < 0)
869*4882a593Smuzhiyun goto fail;
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1));
872*4882a593Smuzhiyun if (status < 0)
873*4882a593Smuzhiyun goto fail;
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100));
876*4882a593Smuzhiyun if (status < 0)
877*4882a593Smuzhiyun goto fail;
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun return 0;
880*4882a593Smuzhiyun fail:
881*4882a593Smuzhiyun dev_err(&the_menelaus->client->dev, "rtc write reg %02x, err %d\n",
882*4882a593Smuzhiyun --regnum, status);
883*4882a593Smuzhiyun return status;
884*4882a593Smuzhiyun }
885*4882a593Smuzhiyun
menelaus_read_time(struct device * dev,struct rtc_time * t)886*4882a593Smuzhiyun static int menelaus_read_time(struct device *dev, struct rtc_time *t)
887*4882a593Smuzhiyun {
888*4882a593Smuzhiyun struct i2c_msg msg[2];
889*4882a593Smuzhiyun char regs[7];
890*4882a593Smuzhiyun int status;
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun /* block read date and time registers */
893*4882a593Smuzhiyun regs[0] = MENELAUS_RTC_SEC;
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun msg[0].addr = MENELAUS_I2C_ADDRESS;
896*4882a593Smuzhiyun msg[0].flags = 0;
897*4882a593Smuzhiyun msg[0].len = 1;
898*4882a593Smuzhiyun msg[0].buf = regs;
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun msg[1].addr = MENELAUS_I2C_ADDRESS;
901*4882a593Smuzhiyun msg[1].flags = I2C_M_RD;
902*4882a593Smuzhiyun msg[1].len = sizeof(regs);
903*4882a593Smuzhiyun msg[1].buf = regs;
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
906*4882a593Smuzhiyun if (status != 2) {
907*4882a593Smuzhiyun dev_err(dev, "%s error %d\n", "read", status);
908*4882a593Smuzhiyun return -EIO;
909*4882a593Smuzhiyun }
910*4882a593Smuzhiyun
911*4882a593Smuzhiyun menelaus_to_time(regs, t);
912*4882a593Smuzhiyun t->tm_wday = bcd2bin(regs[6]);
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun return 0;
915*4882a593Smuzhiyun }
916*4882a593Smuzhiyun
menelaus_set_time(struct device * dev,struct rtc_time * t)917*4882a593Smuzhiyun static int menelaus_set_time(struct device *dev, struct rtc_time *t)
918*4882a593Smuzhiyun {
919*4882a593Smuzhiyun int status;
920*4882a593Smuzhiyun
921*4882a593Smuzhiyun /* write date and time registers */
922*4882a593Smuzhiyun status = time_to_menelaus(t, MENELAUS_RTC_SEC);
923*4882a593Smuzhiyun if (status < 0)
924*4882a593Smuzhiyun return status;
925*4882a593Smuzhiyun status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
926*4882a593Smuzhiyun if (status < 0) {
927*4882a593Smuzhiyun dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
928*4882a593Smuzhiyun "err %d\n", MENELAUS_RTC_WKDAY, status);
929*4882a593Smuzhiyun return status;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun /* now commit the write */
933*4882a593Smuzhiyun status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
934*4882a593Smuzhiyun if (status < 0)
935*4882a593Smuzhiyun dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n",
936*4882a593Smuzhiyun status);
937*4882a593Smuzhiyun
938*4882a593Smuzhiyun return 0;
939*4882a593Smuzhiyun }
940*4882a593Smuzhiyun
menelaus_read_alarm(struct device * dev,struct rtc_wkalrm * w)941*4882a593Smuzhiyun static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
942*4882a593Smuzhiyun {
943*4882a593Smuzhiyun struct i2c_msg msg[2];
944*4882a593Smuzhiyun char regs[6];
945*4882a593Smuzhiyun int status;
946*4882a593Smuzhiyun
947*4882a593Smuzhiyun /* block read alarm registers */
948*4882a593Smuzhiyun regs[0] = MENELAUS_RTC_AL_SEC;
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun msg[0].addr = MENELAUS_I2C_ADDRESS;
951*4882a593Smuzhiyun msg[0].flags = 0;
952*4882a593Smuzhiyun msg[0].len = 1;
953*4882a593Smuzhiyun msg[0].buf = regs;
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun msg[1].addr = MENELAUS_I2C_ADDRESS;
956*4882a593Smuzhiyun msg[1].flags = I2C_M_RD;
957*4882a593Smuzhiyun msg[1].len = sizeof(regs);
958*4882a593Smuzhiyun msg[1].buf = regs;
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
961*4882a593Smuzhiyun if (status != 2) {
962*4882a593Smuzhiyun dev_err(dev, "%s error %d\n", "alarm read", status);
963*4882a593Smuzhiyun return -EIO;
964*4882a593Smuzhiyun }
965*4882a593Smuzhiyun
966*4882a593Smuzhiyun menelaus_to_time(regs, &w->time);
967*4882a593Smuzhiyun
968*4882a593Smuzhiyun w->enabled = !!(the_menelaus->rtc_control & RTC_CTRL_AL_EN);
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun /* NOTE we *could* check if actually pending... */
971*4882a593Smuzhiyun w->pending = 0;
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun return 0;
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun
menelaus_set_alarm(struct device * dev,struct rtc_wkalrm * w)976*4882a593Smuzhiyun static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun int status;
979*4882a593Smuzhiyun
980*4882a593Smuzhiyun if (the_menelaus->client->irq <= 0 && w->enabled)
981*4882a593Smuzhiyun return -ENODEV;
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun /* clear previous alarm enable */
984*4882a593Smuzhiyun if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) {
985*4882a593Smuzhiyun the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
986*4882a593Smuzhiyun status = menelaus_write_reg(MENELAUS_RTC_CTRL,
987*4882a593Smuzhiyun the_menelaus->rtc_control);
988*4882a593Smuzhiyun if (status < 0)
989*4882a593Smuzhiyun return status;
990*4882a593Smuzhiyun }
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun /* write alarm registers */
993*4882a593Smuzhiyun status = time_to_menelaus(&w->time, MENELAUS_RTC_AL_SEC);
994*4882a593Smuzhiyun if (status < 0)
995*4882a593Smuzhiyun return status;
996*4882a593Smuzhiyun
997*4882a593Smuzhiyun /* enable alarm if requested */
998*4882a593Smuzhiyun if (w->enabled) {
999*4882a593Smuzhiyun the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
1000*4882a593Smuzhiyun status = menelaus_write_reg(MENELAUS_RTC_CTRL,
1001*4882a593Smuzhiyun the_menelaus->rtc_control);
1002*4882a593Smuzhiyun }
1003*4882a593Smuzhiyun
1004*4882a593Smuzhiyun return status;
1005*4882a593Smuzhiyun }
1006*4882a593Smuzhiyun
1007*4882a593Smuzhiyun #ifdef CONFIG_RTC_INTF_DEV
1008*4882a593Smuzhiyun
menelaus_rtc_update_work(struct menelaus_chip * m)1009*4882a593Smuzhiyun static void menelaus_rtc_update_work(struct menelaus_chip *m)
1010*4882a593Smuzhiyun {
1011*4882a593Smuzhiyun /* report 1/sec update */
1012*4882a593Smuzhiyun rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF);
1013*4882a593Smuzhiyun }
1014*4882a593Smuzhiyun
menelaus_ioctl(struct device * dev,unsigned cmd,unsigned long arg)1015*4882a593Smuzhiyun static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
1016*4882a593Smuzhiyun {
1017*4882a593Smuzhiyun int status;
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun if (the_menelaus->client->irq <= 0)
1020*4882a593Smuzhiyun return -ENOIOCTLCMD;
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun switch (cmd) {
1023*4882a593Smuzhiyun /* alarm IRQ */
1024*4882a593Smuzhiyun case RTC_AIE_ON:
1025*4882a593Smuzhiyun if (the_menelaus->rtc_control & RTC_CTRL_AL_EN)
1026*4882a593Smuzhiyun return 0;
1027*4882a593Smuzhiyun the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
1028*4882a593Smuzhiyun break;
1029*4882a593Smuzhiyun case RTC_AIE_OFF:
1030*4882a593Smuzhiyun if (!(the_menelaus->rtc_control & RTC_CTRL_AL_EN))
1031*4882a593Smuzhiyun return 0;
1032*4882a593Smuzhiyun the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
1033*4882a593Smuzhiyun break;
1034*4882a593Smuzhiyun /* 1/second "update" IRQ */
1035*4882a593Smuzhiyun case RTC_UIE_ON:
1036*4882a593Smuzhiyun if (the_menelaus->uie)
1037*4882a593Smuzhiyun return 0;
1038*4882a593Smuzhiyun status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
1039*4882a593Smuzhiyun status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
1040*4882a593Smuzhiyun menelaus_rtc_update_work);
1041*4882a593Smuzhiyun if (status == 0)
1042*4882a593Smuzhiyun the_menelaus->uie = 1;
1043*4882a593Smuzhiyun return status;
1044*4882a593Smuzhiyun case RTC_UIE_OFF:
1045*4882a593Smuzhiyun if (!the_menelaus->uie)
1046*4882a593Smuzhiyun return 0;
1047*4882a593Smuzhiyun status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
1048*4882a593Smuzhiyun if (status == 0)
1049*4882a593Smuzhiyun the_menelaus->uie = 0;
1050*4882a593Smuzhiyun return status;
1051*4882a593Smuzhiyun default:
1052*4882a593Smuzhiyun return -ENOIOCTLCMD;
1053*4882a593Smuzhiyun }
1054*4882a593Smuzhiyun return menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
1055*4882a593Smuzhiyun }
1056*4882a593Smuzhiyun
1057*4882a593Smuzhiyun #else
1058*4882a593Smuzhiyun #define menelaus_ioctl NULL
1059*4882a593Smuzhiyun #endif
1060*4882a593Smuzhiyun
1061*4882a593Smuzhiyun /* REVISIT no compensation register support ... */
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun static const struct rtc_class_ops menelaus_rtc_ops = {
1064*4882a593Smuzhiyun .ioctl = menelaus_ioctl,
1065*4882a593Smuzhiyun .read_time = menelaus_read_time,
1066*4882a593Smuzhiyun .set_time = menelaus_set_time,
1067*4882a593Smuzhiyun .read_alarm = menelaus_read_alarm,
1068*4882a593Smuzhiyun .set_alarm = menelaus_set_alarm,
1069*4882a593Smuzhiyun };
1070*4882a593Smuzhiyun
menelaus_rtc_alarm_work(struct menelaus_chip * m)1071*4882a593Smuzhiyun static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
1072*4882a593Smuzhiyun {
1073*4882a593Smuzhiyun /* report alarm */
1074*4882a593Smuzhiyun rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF);
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun /* then disable it; alarms are oneshot */
1077*4882a593Smuzhiyun the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
1078*4882a593Smuzhiyun menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
1079*4882a593Smuzhiyun }
1080*4882a593Smuzhiyun
menelaus_rtc_init(struct menelaus_chip * m)1081*4882a593Smuzhiyun static inline void menelaus_rtc_init(struct menelaus_chip *m)
1082*4882a593Smuzhiyun {
1083*4882a593Smuzhiyun int alarm = (m->client->irq > 0);
1084*4882a593Smuzhiyun int err;
1085*4882a593Smuzhiyun
1086*4882a593Smuzhiyun /* assume 32KDETEN pin is pulled high */
1087*4882a593Smuzhiyun if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
1088*4882a593Smuzhiyun dev_dbg(&m->client->dev, "no 32k oscillator\n");
1089*4882a593Smuzhiyun return;
1090*4882a593Smuzhiyun }
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun m->rtc = devm_rtc_allocate_device(&m->client->dev);
1093*4882a593Smuzhiyun if (IS_ERR(m->rtc))
1094*4882a593Smuzhiyun return;
1095*4882a593Smuzhiyun
1096*4882a593Smuzhiyun m->rtc->ops = &menelaus_rtc_ops;
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun /* support RTC alarm; it can issue wakeups */
1099*4882a593Smuzhiyun if (alarm) {
1100*4882a593Smuzhiyun if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
1101*4882a593Smuzhiyun menelaus_rtc_alarm_work) < 0) {
1102*4882a593Smuzhiyun dev_err(&m->client->dev, "can't handle RTC alarm\n");
1103*4882a593Smuzhiyun return;
1104*4882a593Smuzhiyun }
1105*4882a593Smuzhiyun device_init_wakeup(&m->client->dev, 1);
1106*4882a593Smuzhiyun }
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun /* be sure RTC is enabled; allow 1/sec irqs; leave 12hr mode alone */
1109*4882a593Smuzhiyun m->rtc_control = menelaus_read_reg(MENELAUS_RTC_CTRL);
1110*4882a593Smuzhiyun if (!(m->rtc_control & RTC_CTRL_RTC_EN)
1111*4882a593Smuzhiyun || (m->rtc_control & RTC_CTRL_AL_EN)
1112*4882a593Smuzhiyun || (m->rtc_control & RTC_CTRL_EVERY_MASK)) {
1113*4882a593Smuzhiyun if (!(m->rtc_control & RTC_CTRL_RTC_EN)) {
1114*4882a593Smuzhiyun dev_warn(&m->client->dev, "rtc clock needs setting\n");
1115*4882a593Smuzhiyun m->rtc_control |= RTC_CTRL_RTC_EN;
1116*4882a593Smuzhiyun }
1117*4882a593Smuzhiyun m->rtc_control &= ~RTC_CTRL_EVERY_MASK;
1118*4882a593Smuzhiyun m->rtc_control &= ~RTC_CTRL_AL_EN;
1119*4882a593Smuzhiyun menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
1120*4882a593Smuzhiyun }
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun err = rtc_register_device(m->rtc);
1123*4882a593Smuzhiyun if (err) {
1124*4882a593Smuzhiyun if (alarm) {
1125*4882a593Smuzhiyun menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
1126*4882a593Smuzhiyun device_init_wakeup(&m->client->dev, 0);
1127*4882a593Smuzhiyun }
1128*4882a593Smuzhiyun the_menelaus->rtc = NULL;
1129*4882a593Smuzhiyun }
1130*4882a593Smuzhiyun }
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun #else
1133*4882a593Smuzhiyun
menelaus_rtc_init(struct menelaus_chip * m)1134*4882a593Smuzhiyun static inline void menelaus_rtc_init(struct menelaus_chip *m)
1135*4882a593Smuzhiyun {
1136*4882a593Smuzhiyun /* nothing */
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun #endif
1140*4882a593Smuzhiyun
1141*4882a593Smuzhiyun /*-----------------------------------------------------------------------*/
1142*4882a593Smuzhiyun
1143*4882a593Smuzhiyun static struct i2c_driver menelaus_i2c_driver;
1144*4882a593Smuzhiyun
menelaus_probe(struct i2c_client * client,const struct i2c_device_id * id)1145*4882a593Smuzhiyun static int menelaus_probe(struct i2c_client *client,
1146*4882a593Smuzhiyun const struct i2c_device_id *id)
1147*4882a593Smuzhiyun {
1148*4882a593Smuzhiyun struct menelaus_chip *menelaus;
1149*4882a593Smuzhiyun int rev = 0;
1150*4882a593Smuzhiyun int err = 0;
1151*4882a593Smuzhiyun struct menelaus_platform_data *menelaus_pdata =
1152*4882a593Smuzhiyun dev_get_platdata(&client->dev);
1153*4882a593Smuzhiyun
1154*4882a593Smuzhiyun if (the_menelaus) {
1155*4882a593Smuzhiyun dev_dbg(&client->dev, "only one %s for now\n",
1156*4882a593Smuzhiyun DRIVER_NAME);
1157*4882a593Smuzhiyun return -ENODEV;
1158*4882a593Smuzhiyun }
1159*4882a593Smuzhiyun
1160*4882a593Smuzhiyun menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL);
1161*4882a593Smuzhiyun if (!menelaus)
1162*4882a593Smuzhiyun return -ENOMEM;
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun i2c_set_clientdata(client, menelaus);
1165*4882a593Smuzhiyun
1166*4882a593Smuzhiyun the_menelaus = menelaus;
1167*4882a593Smuzhiyun menelaus->client = client;
1168*4882a593Smuzhiyun
1169*4882a593Smuzhiyun /* If a true probe check the device */
1170*4882a593Smuzhiyun rev = menelaus_read_reg(MENELAUS_REV);
1171*4882a593Smuzhiyun if (rev < 0) {
1172*4882a593Smuzhiyun pr_err(DRIVER_NAME ": device not found");
1173*4882a593Smuzhiyun return -ENODEV;
1174*4882a593Smuzhiyun }
1175*4882a593Smuzhiyun
1176*4882a593Smuzhiyun /* Ack and disable all Menelaus interrupts */
1177*4882a593Smuzhiyun menelaus_write_reg(MENELAUS_INT_ACK1, 0xff);
1178*4882a593Smuzhiyun menelaus_write_reg(MENELAUS_INT_ACK2, 0xff);
1179*4882a593Smuzhiyun menelaus_write_reg(MENELAUS_INT_MASK1, 0xff);
1180*4882a593Smuzhiyun menelaus_write_reg(MENELAUS_INT_MASK2, 0xff);
1181*4882a593Smuzhiyun menelaus->mask1 = 0xff;
1182*4882a593Smuzhiyun menelaus->mask2 = 0xff;
1183*4882a593Smuzhiyun
1184*4882a593Smuzhiyun /* Set output buffer strengths */
1185*4882a593Smuzhiyun menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
1186*4882a593Smuzhiyun
1187*4882a593Smuzhiyun if (client->irq > 0) {
1188*4882a593Smuzhiyun err = request_irq(client->irq, menelaus_irq, 0,
1189*4882a593Smuzhiyun DRIVER_NAME, menelaus);
1190*4882a593Smuzhiyun if (err) {
1191*4882a593Smuzhiyun dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
1192*4882a593Smuzhiyun client->irq, err);
1193*4882a593Smuzhiyun return err;
1194*4882a593Smuzhiyun }
1195*4882a593Smuzhiyun }
1196*4882a593Smuzhiyun
1197*4882a593Smuzhiyun mutex_init(&menelaus->lock);
1198*4882a593Smuzhiyun INIT_WORK(&menelaus->work, menelaus_work);
1199*4882a593Smuzhiyun
1200*4882a593Smuzhiyun pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
1201*4882a593Smuzhiyun
1202*4882a593Smuzhiyun err = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
1203*4882a593Smuzhiyun if (err < 0)
1204*4882a593Smuzhiyun goto fail;
1205*4882a593Smuzhiyun if (err & VCORE_CTRL1_HW_NSW)
1206*4882a593Smuzhiyun menelaus->vcore_hw_mode = 1;
1207*4882a593Smuzhiyun else
1208*4882a593Smuzhiyun menelaus->vcore_hw_mode = 0;
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
1211*4882a593Smuzhiyun err = menelaus_pdata->late_init(&client->dev);
1212*4882a593Smuzhiyun if (err < 0)
1213*4882a593Smuzhiyun goto fail;
1214*4882a593Smuzhiyun }
1215*4882a593Smuzhiyun
1216*4882a593Smuzhiyun menelaus_rtc_init(menelaus);
1217*4882a593Smuzhiyun
1218*4882a593Smuzhiyun return 0;
1219*4882a593Smuzhiyun fail:
1220*4882a593Smuzhiyun free_irq(client->irq, menelaus);
1221*4882a593Smuzhiyun flush_work(&menelaus->work);
1222*4882a593Smuzhiyun return err;
1223*4882a593Smuzhiyun }
1224*4882a593Smuzhiyun
menelaus_remove(struct i2c_client * client)1225*4882a593Smuzhiyun static int menelaus_remove(struct i2c_client *client)
1226*4882a593Smuzhiyun {
1227*4882a593Smuzhiyun struct menelaus_chip *menelaus = i2c_get_clientdata(client);
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun free_irq(client->irq, menelaus);
1230*4882a593Smuzhiyun flush_work(&menelaus->work);
1231*4882a593Smuzhiyun the_menelaus = NULL;
1232*4882a593Smuzhiyun return 0;
1233*4882a593Smuzhiyun }
1234*4882a593Smuzhiyun
1235*4882a593Smuzhiyun static const struct i2c_device_id menelaus_id[] = {
1236*4882a593Smuzhiyun { "menelaus", 0 },
1237*4882a593Smuzhiyun { }
1238*4882a593Smuzhiyun };
1239*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, menelaus_id);
1240*4882a593Smuzhiyun
1241*4882a593Smuzhiyun static struct i2c_driver menelaus_i2c_driver = {
1242*4882a593Smuzhiyun .driver = {
1243*4882a593Smuzhiyun .name = DRIVER_NAME,
1244*4882a593Smuzhiyun },
1245*4882a593Smuzhiyun .probe = menelaus_probe,
1246*4882a593Smuzhiyun .remove = menelaus_remove,
1247*4882a593Smuzhiyun .id_table = menelaus_id,
1248*4882a593Smuzhiyun };
1249*4882a593Smuzhiyun
1250*4882a593Smuzhiyun module_i2c_driver(menelaus_i2c_driver);
1251*4882a593Smuzhiyun
1252*4882a593Smuzhiyun MODULE_AUTHOR("Texas Instruments, Inc. (and others)");
1253*4882a593Smuzhiyun MODULE_DESCRIPTION("I2C interface for Menelaus.");
1254*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1255