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