^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) * lm3533-ctrlbank.c -- LM3533 Generic Control Bank interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2011-2012 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Johan Hovold <jhovold@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mfd/lm3533.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define LM3533_MAX_CURRENT_MIN 5000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define LM3533_MAX_CURRENT_MAX 29800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define LM3533_MAX_CURRENT_STEP 800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define LM3533_PWM_MAX 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define LM3533_REG_PWM_BASE 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define LM3533_REG_MAX_CURRENT_BASE 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define LM3533_REG_CTRLBANK_ENABLE 0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define LM3533_REG_BRIGHTNESS_BASE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static inline u8 lm3533_ctrlbank_get_reg(struct lm3533_ctrlbank *cb, u8 base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return base + cb->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mask = 1 << cb->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) mask, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) dev_err(cb->dev, "failed to enable ctrlbank %d\n", cb->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) EXPORT_SYMBOL_GPL(lm3533_ctrlbank_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mask = 1 << cb->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, 0, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) dev_err(cb->dev, "failed to disable ctrlbank %d\n", cb->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) EXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Full-scale current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * imax 5000 - 29800 uA (800 uA step)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (imax < LM3533_MAX_CURRENT_MIN || imax > LM3533_MAX_CURRENT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) ret = lm3533_write(cb->lm3533, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) dev_err(cb->dev, "failed to set max current\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ret = lm3533_write(cb->lm3533, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) dev_err(cb->dev, "failed to set brightness\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = lm3533_read(cb->lm3533, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) dev_err(cb->dev, "failed to get brightness\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * PWM-input control mask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * bit 5 - PWM-input enabled in Zone 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * bit 4 - PWM-input enabled in Zone 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * bit 3 - PWM-input enabled in Zone 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * bit 2 - PWM-input enabled in Zone 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * bit 1 - PWM-input enabled in Zone 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * bit 0 - PWM-input enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (val > LM3533_PWM_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) ret = lm3533_write(cb->lm3533, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev_err(cb->dev, "failed to set PWM mask\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret = lm3533_read(cb->lm3533, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dev_err(cb->dev, "failed to get PWM mask\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) MODULE_DESCRIPTION("LM3533 Control Bank interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) MODULE_LICENSE("GPL");