116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold/*
216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * lm3533-ctrlbank.c -- LM3533 Generic Control Bank interface
316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *
416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * Copyright (C) 2011-2012 Texas Instruments
516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *
616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * Author: Johan Hovold <jhovold@gmail.com>
716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *
816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * This program is free software; you can redistribute it and/or modify it
916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * under  the terms of the GNU General  Public License as published by the
1016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * Free Software Foundation;  either version 2 of the License, or (at your
1116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * option) any later version.
1216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold */
1316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
1416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#include <linux/device.h>
1516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#include <linux/module.h>
1616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
1716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#include <linux/mfd/lm3533.h>
1816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
1916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
206fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold#define LM3533_MAX_CURRENT_MIN		5000
216fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold#define LM3533_MAX_CURRENT_MAX		29800
226fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold#define LM3533_MAX_CURRENT_STEP		800
236fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold
2416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define LM3533_BRIGHTNESS_MAX		255
2516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define LM3533_PWM_MAX			0x3f
2616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
2716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define LM3533_REG_PWM_BASE		0x14
2816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define LM3533_REG_MAX_CURRENT_BASE	0x1f
2916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define LM3533_REG_CTRLBANK_ENABLE	0x27
3016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define LM3533_REG_BRIGHTNESS_BASE	0x40
3116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
3216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
3316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldstatic inline u8 lm3533_ctrlbank_get_reg(struct lm3533_ctrlbank *cb, u8 base)
3416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold{
3516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	return base + cb->id;
3616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold}
3716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
3816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldint lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb)
3916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold{
4016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	u8 mask;
4116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	int ret;
4216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
4316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
4416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
4516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	mask = 1 << cb->id;
4616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE,
4716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold								mask, mask);
4816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	if (ret)
4916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold		dev_err(cb->dev, "failed to enable ctrlbank %d\n", cb->id);
5016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
5116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	return ret;
5216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold}
5316c5c023aac86228e3e94c4bf6d19708ea861a05Johan HovoldEXPORT_SYMBOL_GPL(lm3533_ctrlbank_enable);
5416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
5516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldint lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb)
5616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold{
5716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	u8 mask;
5816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	int ret;
5916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
6016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
6116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
6216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	mask = 1 << cb->id;
6316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, 0, mask);
6416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	if (ret)
6516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold		dev_err(cb->dev, "failed to disable ctrlbank %d\n", cb->id);
6616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
6716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	return ret;
6816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold}
6916c5c023aac86228e3e94c4bf6d19708ea861a05Johan HovoldEXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable);
7016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
716fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold/*
726fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold * Full-scale current.
736fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold *
746fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold * imax		5000 - 29800 uA (800 uA step)
756fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold */
766fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovoldint lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
776fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold{
786fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	u8 reg;
796fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	u8 val;
806fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	int ret;
816fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold
826fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	if (imax < LM3533_MAX_CURRENT_MIN || imax > LM3533_MAX_CURRENT_MAX)
836fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold		return -EINVAL;
846fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold
856fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP;
866fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold
876fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE);
886fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	ret = lm3533_write(cb->lm3533, reg, val);
896fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	if (ret)
906fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold		dev_err(cb->dev, "failed to set max current\n");
916fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold
926fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold	return ret;
936fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold}
946fa4b9d802610116adf4b89c2f9bd155829aafd3Johan HovoldEXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current);
956fa4b9d802610116adf4b89c2f9bd155829aafd3Johan Hovold
9616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define lm3533_ctrlbank_set(_name, _NAME)				\
9716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldint lm3533_ctrlbank_set_##_name(struct lm3533_ctrlbank *cb, u8 val)	\
9816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold{									\
9916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	u8 reg;								\
10016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	int ret;							\
10116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold									\
10216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	if (val > LM3533_##_NAME##_MAX)					\
10316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold		return -EINVAL;						\
10416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold									\
10516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE);	\
10616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	ret = lm3533_write(cb->lm3533, reg, val);			\
10716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	if (ret)							\
10816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold		dev_err(cb->dev, "failed to set " #_name "\n");		\
10916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold									\
11016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	return ret;							\
11116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold}									\
11216c5c023aac86228e3e94c4bf6d19708ea861a05Johan HovoldEXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_##_name);
11316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
11416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold#define lm3533_ctrlbank_get(_name, _NAME)				\
11516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldint lm3533_ctrlbank_get_##_name(struct lm3533_ctrlbank *cb, u8 *val)	\
11616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold{									\
11716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	u8 reg;								\
11816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	int ret;							\
11916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold									\
12016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE);	\
12116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	ret = lm3533_read(cb->lm3533, reg, val);			\
12216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	if (ret)							\
12316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold		dev_err(cb->dev, "failed to get " #_name "\n");		\
12416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold									\
12516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold	return ret;							\
12616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold}									\
12716c5c023aac86228e3e94c4bf6d19708ea861a05Johan HovoldEXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_##_name);
12816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
12916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldlm3533_ctrlbank_set(brightness, BRIGHTNESS);
13016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldlm3533_ctrlbank_get(brightness, BRIGHTNESS);
13116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
13216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold/*
13316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold * PWM-input control mask:
13416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *
13516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *   bit 5 - PWM-input enabled in Zone 4
13616c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *   bit 4 - PWM-input enabled in Zone 3
13716c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *   bit 3 - PWM-input enabled in Zone 2
13816c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *   bit 2 - PWM-input enabled in Zone 1
13916c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *   bit 1 - PWM-input enabled in Zone 0
14016c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold *   bit 0 - PWM-input enabled
14116c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold */
14216c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldlm3533_ctrlbank_set(pwm, PWM);
14316c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovoldlm3533_ctrlbank_get(pwm, PWM);
14416c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
14516c5c023aac86228e3e94c4bf6d19708ea861a05Johan Hovold
14616c5c023aac86228e3e94c4bf6d19708ea861a05Johan HovoldMODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
14716c5c023aac86228e3e94c4bf6d19708ea861a05Johan HovoldMODULE_DESCRIPTION("LM3533 Control Bank interface");
14816c5c023aac86228e3e94c4bf6d19708ea861a05Johan HovoldMODULE_LICENSE("GPL");
149