QC3P:add iio sys support

Add iio sys support for
QC3P turbo charger.

Change-Id: Ib8c626e912becd75d751fda7e6050a39fcc0785c
Signed-off-by: xuwei9 <xuwei9@lenovo.com>
Reviewed-on: https://gerrit.mot.com/2139278
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
xuwei9 2021-12-09 11:23:47 +08:00 committed by Wei Xu
parent fdb761671a
commit 77aa01676c
2 changed files with 201 additions and 2 deletions

View file

@ -1,5 +1,8 @@
#ifndef __QC3P_WT6670_
#define __QC3P_WT6670_
#include <linux/iio/iio.h>
#include <dt-bindings/iio/qti_power_supply_iio.h>
#include <linux/iio/consumer.h>
#define WT6670_FIRMWARE_VERSION 0x03
@ -14,6 +17,9 @@ struct wt6670f {
int count;
int chg_type;
bool chg_ready;
struct iio_dev *indio_dev;
struct iio_chan_spec *iio_chan;
struct iio_channel *int_iio_chans;
struct mutex i2c_rw_lock;
};
@ -23,6 +29,47 @@ enum {
QC3P_Z350,
};
enum wt6670_charger_type{
WT6670_CHG_TYPE_BEGIN = 0,
WT6670_CHG_TYPE_FC,
WT6670_CHG_TYPE_SDP,
WT6670_CHG_TYPE_CDP,
WT6670_CHG_TYPE_DCP,
WT6670_CHG_TYPE_QC2,
WT6670_CHG_TYPE_QC3,
WT6670_CHG_TYPE_OCP,
WT6670_CHG_TYPE_QC3P_18W,
WT6670_CHG_TYPE_QC3P_27W,
WT6670_CHG_TYPE_UNKNOWN,
};
struct wt6670_iio_channels {
const char *datasheet_name;
int channel_num;
enum iio_chan_type type;
long info_mask;
};
#define wt6670_IIO_CHAN(_name, _num, _type, _mask) \
{ \
.datasheet_name = _name, \
.channel_num = _num, \
.type = _type, \
.info_mask = _mask, \
},
#define wt6670_CHAN_INDEX(_name, _num) \
wt6670_IIO_CHAN(_name, _num, IIO_INDEX, \
BIT(IIO_CHAN_INFO_PROCESSED))
static const struct wt6670_iio_channels wt6670_iio_psy_channels[] = {
wt6670_CHAN_INDEX("wt6670_usb_real_type", PSY_IIO_QC3P_REAL_TYPE)
wt6670_CHAN_INDEX("wt6670_usb_qc3p_power", PSY_IIO_QC3P_POWER)
wt6670_CHAN_INDEX("wt6670_battery_dp_dm", PSY_IIO_BATTERY_DP_DM)
wt6670_CHAN_INDEX("wt6670_start_detection", PSY_IIO_START_DETECTION)
wt6670_CHAN_INDEX("wt6670_detection_ready", PSY_IIO_DETECTION_READY)
};
int wt6670f_isp_flow(struct wt6670f *chip);
int wt6670f_get_firmware_version(void);
#endif //__QC3P_WT6670_

View file

@ -450,6 +450,146 @@ EXPORT_SYMBOL_GPL(moto_tcmd_wt6670f_get_firmware_version);
return 0;
}*/
static int wt6670_iio_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val1,
int val2, long mask)
{
int rc = 0;
switch (chan->channel) {
case PSY_IIO_START_DETECTION:
wt6670f_reset_chg_type();
wt6670f_start_detection();
pr_info("wt6670 start detection\n");
break;
case PSY_IIO_BATTERY_DP_DM:
wt6670f_set_volt_count(val1);
pr_info("wt6670 set volt count:%d\n",val1);
break;
default:
pr_err("Unsupported wt6670 IIO chan %d\n", chan->channel);
rc = -EINVAL;
break;
}
if (rc < 0)
pr_err("Couldn't write IIO channel %d, rc = %d\n",
chan->channel, rc);
return rc;
}
static int wt6670_iio_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val1,
int *val2, long mask)
{
int rc = 0;
int result;
*val1 = 0;
switch (chan->channel) {
case PSY_IIO_QC3P_POWER:
result = wt6670f_get_charger_type();
pr_info("wt6670 get charger type for qc3p power:%d\n",result);
if(result == WT6670_CHG_TYPE_QC3P_18W || result == WT6670_CHG_TYPE_QC3P_27W)
*val1 = result;
break;
case PSY_IIO_QC3P_REAL_TYPE:
wt6670f_get_protocol();
result = wt6670f_get_charger_type();
pr_info("wt6670 get charger type:%d\n", result);
*val1 = result;
break;
case PSY_IIO_DETECTION_READY:
result = wt6670f_is_charger_ready();
pr_info("wt6670 get wt6670f_is_charger_ready status:%d\n", result);
*val1 = result;
break;
default:
pr_err("Unsupported wt6670 IIO chan %d\n", chan->channel);
rc = -EINVAL;
break;
}
if (rc < 0) {
pr_err("Couldn't read IIO channel %d, rc = %d\n",
chan->channel, rc);
return rc;
}
return IIO_VAL_INT;
}
static int wt6670_iio_of_xlate(struct iio_dev *indio_dev,
const struct of_phandle_args *iiospec)
{
struct wt6670f *bq = iio_priv(indio_dev);
struct iio_chan_spec *iio_chan = bq->iio_chan;
int i;
for (i = 0; i < ARRAY_SIZE(wt6670_iio_psy_channels);
i++, iio_chan++)
if (iio_chan->channel == iiospec->args[0])
return i;
return -EINVAL;
}
static const struct iio_info wt6670_iio_info = {
.read_raw = wt6670_iio_read_raw,
.write_raw = wt6670_iio_write_raw,
.of_xlate = wt6670_iio_of_xlate,
};
static int wt6670_init_iio_psy(struct wt6670f *chip)
{
struct iio_dev *indio_dev = chip->indio_dev;
struct iio_chan_spec *chan;
int wt6670_num_iio_channels = ARRAY_SIZE(wt6670_iio_psy_channels);
int rc, i;
chip->iio_chan = devm_kcalloc(chip->dev, wt6670_num_iio_channels,
sizeof(*chip->iio_chan), GFP_KERNEL);
if (!chip->iio_chan)
return -ENOMEM;
chip->int_iio_chans = devm_kcalloc(chip->dev,
wt6670_num_iio_channels,
sizeof(*chip->int_iio_chans),
GFP_KERNEL);
if (!chip->int_iio_chans)
return -ENOMEM;
indio_dev->info = &wt6670_iio_info;
indio_dev->dev.parent = chip->dev;
indio_dev->dev.of_node = chip->dev->of_node;
indio_dev->name = "wt6670";
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = chip->iio_chan;
indio_dev->num_channels = wt6670_num_iio_channels;
for (i = 0; i < wt6670_num_iio_channels; i++) {
chip->int_iio_chans[i].indio_dev = indio_dev;
chan = &chip->iio_chan[i];
chip->int_iio_chans[i].channel = chan;
chan->address = i;
chan->channel = wt6670_iio_psy_channels[i].channel_num;
chan->type = wt6670_iio_psy_channels[i].type;
chan->datasheet_name =
wt6670_iio_psy_channels[i].datasheet_name;
chan->extend_name =
wt6670_iio_psy_channels[i].datasheet_name;
chan->info_mask_separate =
wt6670_iio_psy_channels[i].info_mask;
}
rc = devm_iio_device_register(chip->dev, indio_dev);
if (rc)
pr_err("Failed to register wt6670 IIO device, rc=%d\n", rc);
return rc;
}
extern int wt6670f_isp_flow(struct wt6670f *chip);
static int wt6670f_i2c_probe(struct i2c_client *client,
@ -459,13 +599,21 @@ static int wt6670f_i2c_probe(struct i2c_client *client,
u16 firmware_version = 0;
int in_isp_flow_count = 3;
struct wt6670f *wt;
struct iio_dev *indio_dev;
pr_info("[%s]\n", __func__);
wt = devm_kzalloc(&client->dev, sizeof(struct wt6670f), GFP_KERNEL);
if (!wt)
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*wt));
if (!indio_dev)
return -ENOMEM;
wt = iio_priv(indio_dev);
if (!wt) {
pr_err("Out of memory\n");
return -ENOMEM;
}
wt->indio_dev = indio_dev;
wt->dev = &client->dev;
wt->client = client;
i2c_set_clientdata(client, wt);
@ -507,6 +655,10 @@ static int wt6670f_i2c_probe(struct i2c_client *client,
}
}
ret = wt6670_init_iio_psy(wt);
if (ret < 0)
pr_info("%s: init iio sys error\n", __func__);
return 0;
}