^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2020 MaxLinear, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This driver is a hardware monitoring driver for PVT controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * (MR75203) which is used to configure & control Moortec embedded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * analog IP to enable multiple embedded temperature sensor(TS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * voltage monitor(VM) & process detector(PD) modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* PVT Common register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PVT_IP_CONFIG 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define TS_NUM_MSK GENMASK(4, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define TS_NUM_SFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PD_NUM_MSK GENMASK(12, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PD_NUM_SFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define VM_NUM_MSK GENMASK(20, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define VM_NUM_SFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CH_NUM_MSK GENMASK(31, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CH_NUM_SFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* Macro Common Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CLK_SYNTH 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CLK_SYNTH_LO_SFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CLK_SYNTH_HI_SFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define CLK_SYNTH_HOLD_SFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CLK_SYNTH_EN BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CLK_SYS_CYCLES_MAX 514
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CLK_SYS_CYCLES_MIN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define HZ_PER_MHZ 1000000L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SDIF_DISABLE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SDIF_STAT 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SDIF_BUSY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SDIF_LOCK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SDIF_W 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SDIF_PROG BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SDIF_WRN_W BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SDIF_WRN_R 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SDIF_ADDR_SFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SDIF_HALT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SDIF_CTRL 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SDIF_SMPL_CTRL 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* TS & PD Individual Macro Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define COM_REG_SIZE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SDIF_DONE(n) (COM_REG_SIZE + 0x14 + 0x40 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SDIF_SMPL_DONE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SDIF_DATA(n) (COM_REG_SIZE + 0x18 + 0x40 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SAMPLE_DATA_MSK GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define HILO_RESET(n) (COM_REG_SIZE + 0x2c + 0x40 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* VM Individual Macro Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define VM_COM_REG_SIZE 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define VM_SDIF_DONE(n) (VM_COM_REG_SIZE + 0x34 + 0x200 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define VM_SDIF_DATA(n) (VM_COM_REG_SIZE + 0x40 + 0x200 * (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* SDA Slave Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define IP_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IP_RST_REL BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IP_RUN_CONT BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define IP_AUTO BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define IP_VM_MODE BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define IP_CFG 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define CFG0_MODE_2 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define CFG0_PARALLEL_OUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define CFG0_12_BIT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define CFG1_VOL_MEAS_MODE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define CFG1_PARALLEL_OUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define CFG1_14_BIT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IP_DATA 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define IP_POLL 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define VM_CH_INIT BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define VM_CH_REQ BIT(21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define IP_TMR 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define POWER_DELAY_CYCLE_256 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define POWER_DELAY_CYCLE_64 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define PVT_POLL_DELAY_US 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define PVT_POLL_TIMEOUT_US 20000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define PVT_H_CONST 100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define PVT_CAL5_CONST 2047
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define PVT_G_CONST 40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define PVT_CONV_BITS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define PVT_N_CONST 90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define PVT_R_CONST 245805
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct pvt_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct regmap *c_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct regmap *t_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct regmap *p_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct regmap *v_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct reset_control *rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 t_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u32 p_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u32 v_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 ip_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 *vm_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static umode_t pvt_is_visible(const void *data, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u32 attr, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (attr == hwmon_temp_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (attr == hwmon_in_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int pvt_read_temp(struct device *dev, u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct pvt_device *pvt = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct regmap *t_map = pvt->t_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 stat, nbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ret = regmap_read_poll_timeout(t_map, SDIF_DONE(channel),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) stat, stat & SDIF_SMPL_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ret = regmap_read(t_map, SDIF_DATA(channel), &nbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) nbs &= SAMPLE_DATA_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Convert the register value to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * degrees centigrade temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) tmp = nbs * PVT_H_CONST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) do_div(tmp, PVT_CAL5_CONST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *val = tmp - PVT_G_CONST - pvt->ip_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct pvt_device *pvt = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct regmap *v_map = pvt->v_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u32 n, stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u8 vm_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (channel >= pvt->v_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) vm_idx = pvt->vm_idx[channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case hwmon_in_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret = regmap_read_poll_timeout(v_map, VM_SDIF_DONE(vm_idx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) stat, stat & SDIF_SMPL_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx), &n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) n &= SAMPLE_DATA_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Convert the N bitstream count into voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *val = (PVT_N_CONST * n - PVT_R_CONST) >> PVT_CONV_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int pvt_read(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case hwmon_temp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return pvt_read_temp(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case hwmon_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return pvt_read_in(dev, attr, channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static const u32 pvt_chip_config[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) HWMON_C_REGISTER_TZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static const struct hwmon_channel_info pvt_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .type = hwmon_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .config = pvt_chip_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static struct hwmon_channel_info pvt_temp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .type = hwmon_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static struct hwmon_channel_info pvt_in = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .type = hwmon_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static const struct hwmon_ops pvt_hwmon_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .is_visible = pvt_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .read = pvt_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static struct hwmon_chip_info pvt_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .ops = &pvt_hwmon_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int pvt_init(struct pvt_device *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u16 sys_freq, key, middle, low = 4, high = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct regmap *t_map = pvt->t_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct regmap *p_map = pvt->p_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct regmap *v_map = pvt->v_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u32 t_num = pvt->t_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u32 p_num = pvt->p_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u32 v_num = pvt->v_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) u32 clk_synth, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) sys_freq = clk_get_rate(pvt->clk) / HZ_PER_MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) while (high >= low) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) middle = (low + high + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) key = DIV_ROUND_CLOSEST(sys_freq, middle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (key > CLK_SYS_CYCLES_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) low = middle + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) } else if (key < CLK_SYS_CYCLES_MIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) high = middle - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * The system supports 'clk_sys' to 'clk_ip' frequency ratios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * from 2:1 to 512:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) key = clamp_val(key, CLK_SYS_CYCLES_MIN, CLK_SYS_CYCLES_MAX) - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) clk_synth = ((key + 1) >> 1) << CLK_SYNTH_LO_SFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) (key >> 1) << CLK_SYNTH_HI_SFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) (key >> 1) << CLK_SYNTH_HOLD_SFT | CLK_SYNTH_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pvt->ip_freq = sys_freq * 100 / (key + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (t_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ret = regmap_write(t_map, SDIF_SMPL_CTRL, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if(ret < 0)
^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) ret = regmap_write(t_map, SDIF_HALT, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ret = regmap_write(t_map, CLK_SYNTH, clk_synth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = regmap_write(t_map, SDIF_DISABLE, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) val, !(val & SDIF_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) val = CFG0_MODE_2 | CFG0_PARALLEL_OUT | CFG0_12_BIT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) IP_CFG << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ret = regmap_write(t_map, SDIF_W, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) val, !(val & SDIF_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) val = POWER_DELAY_CYCLE_256 | IP_TMR << SDIF_ADDR_SFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) SDIF_WRN_W | SDIF_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = regmap_write(t_map, SDIF_W, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) val, !(val & SDIF_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) val = IP_RST_REL | IP_RUN_CONT | IP_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) IP_CTRL << SDIF_ADDR_SFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) SDIF_WRN_W | SDIF_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = regmap_write(t_map, SDIF_W, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (p_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = regmap_write(p_map, SDIF_HALT, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = regmap_write(p_map, SDIF_DISABLE, BIT(p_num) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = regmap_write(p_map, CLK_SYNTH, clk_synth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (v_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ret = regmap_write(v_map, SDIF_SMPL_CTRL, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ret = regmap_write(v_map, SDIF_HALT, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = regmap_write(v_map, CLK_SYNTH, clk_synth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ret = regmap_write(v_map, SDIF_DISABLE, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) val, !(val & SDIF_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) SDIF_WRN_W | SDIF_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ret = regmap_write(v_map, SDIF_W, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) val, !(val & SDIF_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) val = POWER_DELAY_CYCLE_64 | IP_TMR << SDIF_ADDR_SFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) SDIF_WRN_W | SDIF_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = regmap_write(v_map, SDIF_W, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) val, !(val & SDIF_BUSY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) PVT_POLL_DELAY_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) PVT_POLL_TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) val = IP_RST_REL | IP_RUN_CONT | IP_AUTO | IP_VM_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) IP_CTRL << SDIF_ADDR_SFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) SDIF_WRN_W | SDIF_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = regmap_write(v_map, SDIF_W, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if(ret < 0)
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static struct regmap_config pvt_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int pvt_get_regmap(struct platform_device *pdev, char *reg_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct pvt_device *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct regmap **reg_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) void __iomem *io_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!strcmp(reg_name, "common"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) reg_map = &pvt->c_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) else if (!strcmp(reg_name, "ts"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) reg_map = &pvt->t_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) else if (!strcmp(reg_name, "pd"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) reg_map = &pvt->p_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) else if (!strcmp(reg_name, "vm"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) reg_map = &pvt->v_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) io_base = devm_platform_ioremap_resource_byname(pdev, reg_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (IS_ERR(io_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return PTR_ERR(io_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) pvt_regmap_config.name = reg_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) *reg_map = devm_regmap_init_mmio(dev, io_base, &pvt_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (IS_ERR(*reg_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dev_err(dev, "failed to init register map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return PTR_ERR(*reg_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static void pvt_clk_disable(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct pvt_device *pvt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) clk_disable_unprepare(pvt->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static int pvt_clk_enable(struct device *dev, struct pvt_device *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = clk_prepare_enable(pvt->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (ret)
^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) return devm_add_action_or_reset(dev, pvt_clk_disable, pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void pvt_reset_control_assert(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct pvt_device *pvt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) reset_control_assert(pvt->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ret = reset_control_deassert(pvt->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return devm_add_action_or_reset(dev, pvt_reset_control_assert, pvt);
^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 int mr75203_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) const struct hwmon_channel_info **pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) u32 ts_num, vm_num, pd_num, val, index, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) u32 *temp_config, *in_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct pvt_device *pvt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (!pvt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ret = pvt_get_regmap(pdev, "common", pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) pvt->clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (IS_ERR(pvt->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ret = pvt_clk_enable(dev, pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dev_err(dev, "failed to enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) pvt->rst = devm_reset_control_get_exclusive(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (IS_ERR(pvt->rst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return dev_err_probe(dev, PTR_ERR(pvt->rst),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) "failed to get reset control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ret = pvt_reset_control_deassert(dev, pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return dev_err_probe(dev, ret, "cannot deassert reset control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if(ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) pvt->t_num = ts_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pvt->p_num = pd_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) pvt->v_num = vm_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (ts_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) val++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (vm_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) val++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (!pvt_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) pvt_info[0] = &pvt_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (ts_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ret = pvt_get_regmap(pdev, "ts", pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) temp_config = devm_kcalloc(dev, ts_num + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) sizeof(*temp_config), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (!temp_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) memset32(temp_config, HWMON_T_INPUT, ts_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) pvt_temp.config = temp_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) pvt_info[index++] = &pvt_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (pd_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) ret = pvt_get_regmap(pdev, "pd", pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (vm_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) u32 num = vm_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) ret = pvt_get_regmap(pdev, "vm", pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) pvt->vm_idx = devm_kcalloc(dev, vm_num, sizeof(*pvt->vm_idx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!pvt->vm_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ret = device_property_read_u8_array(dev, "intel,vm-map",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) pvt->vm_idx, vm_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) for (i = 0; i < vm_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (pvt->vm_idx[i] >= vm_num ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pvt->vm_idx[i] == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) num = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * Incase intel,vm-map property is not defined, we assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * incremental channel numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) for (i = num; i < vm_num; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) pvt->vm_idx[i] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) in_config = devm_kcalloc(dev, num + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) sizeof(*in_config), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (!in_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) memset32(in_config, HWMON_I_INPUT, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) in_config[num] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) pvt_in.config = in_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) pvt_info[index++] = &pvt_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = pvt_init(pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) dev_err(dev, "failed to init pvt: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) pvt_chip_info.info = pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) pvt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) &pvt_chip_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static const struct of_device_id moortec_pvt_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) { .compatible = "moortec,mr75203" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) MODULE_DEVICE_TABLE(of, moortec_pvt_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static struct platform_driver moortec_pvt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) .name = "moortec-pvt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) .of_match_table = moortec_pvt_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .probe = mr75203_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) module_platform_driver(moortec_pvt_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) MODULE_LICENSE("GPL v2");