charging: add iio psy to provide api for other modules

add iio psy frame to provide api for
other modules

Change-Id: Ibc8478b4ee9b07b843f262555e1d15c5a59fc554
Signed-off-by: mahj8 <mahj8@lenovo.com>
Reviewed-on: https://gerrit.mot.com/2088633
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
mahj8 2021-10-20 10:17:52 +08:00 • committed by Haijian Ma
commit 1837c058f2
5 changed files with 233 additions and 2 deletions

View file

@ -6,6 +6,7 @@ EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include \
obj-m += mmi_discrete_charger.o
mmi_discrete_charger-objs += mmi_discrete_charger_core.o
mmi_discrete_charger-objs += mmi_discrete_charger_iio.o
mmi_discrete_charger-objs += mmi_discrete_voter.o
mmi_discrete_charger-objs += mmi_discrete_factory_tcmd.o

View file

@ -29,6 +29,7 @@
#include "mmi_discrete_charger_core.h"
#include "mmi_discrete_voter.h"
#include "mmi_discrete_charger_iio.h"
#include "mmi_discrete_factory_tcmd.h"
#include <linux/mmi_discrete_charger_class.h>
@ -706,6 +707,22 @@ static int mmi_discrete_disable_hw_jeita(struct mmi_discrete_charger *chip)
return rc;
}
int mmi_discrete_otg_enable(struct mmi_discrete_charger *chip, bool en)
{
int rc = 0;
if (en == !chip->vbus_enabled) {
rc = charger_dev_enable_otg(chip->master_chg_dev, en);
if (rc) {
mmi_err(chip, "Unable to %s otg (%d)\n", en?"enable":"disable", rc);
return rc;
}
chip->vbus_enabled = en;
}
return rc;
}
static void mmi_discrete_check_otg_power(struct mmi_discrete_charger *chip)
{
int rc = 0;
@ -2293,12 +2310,22 @@ static int mmi_discrete_probe(struct platform_device *pdev)
{
int rc = 0;
struct mmi_discrete_charger *chip;
struct iio_dev *indio_dev;
struct power_supply_config psy_cfg = {};
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*chip));
if (!indio_dev)
return -ENOMEM;
chip = iio_priv(indio_dev);
if (!chip) {
dev_err(&pdev->dev,
"Unable to alloc memory for mmi_discrete_iio\n");
return -ENOMEM;
}
chip->indio_dev = indio_dev;
chip->dev = &pdev->dev;
chip->name = "mmi_discrete";
psy_cfg.drv_data = chip;
@ -2336,6 +2363,12 @@ static int mmi_discrete_probe(struct platform_device *pdev)
chip->wls_psy = power_supply_get_by_name("wireless");
rc = mmi_discrete_init_iio_psy(chip, pdev);
if (rc < 0) {
mmi_err(chip, "Failed to init iio psy\n");
return rc;
}
rc = mmi_discrete_parse_dts(chip);
if (rc < 0) {
mmi_err(chip, "Failed to parse dts\n");

View file

@ -13,6 +13,8 @@
#ifndef __MMI_DISCRETE_CHARGER_CORE_H__
#define __MMI_DISCRETE_CHARGER_CORE_H__
#include <linux/iio/consumer.h>
#include <linux/iio/iio.h>
#include <linux/extcon-provider.h>
#include "mmi_charger.h"
@ -102,6 +104,11 @@ struct mmi_discrete_charger {
/* extcon for VBUS / ID notification to USB for type-c only */
struct extcon_dev *extcon;
/*IIO*/
struct iio_dev *indio_dev;
struct iio_chan_spec *iio_chan;
struct iio_channel *int_iio_chans;
/*PD*/
/* struct usbpd *pd_handle;
int pd_current_pdo;
@ -128,4 +135,6 @@ struct mmi_discrete_charger {
bool use_extcon;
};
int mmi_discrete_otg_enable(struct mmi_discrete_charger *chip, bool en);
#endif

View file

@ -0,0 +1,138 @@
/* Copyright (c) 2020, 2021 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "mmi_discrete_charger_iio.h"
static int mmi_discrete_iio_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val1,
int val2, long mask)
{
struct mmi_discrete_charger *chip = iio_priv(indio_dev);
int rc = 0;
switch (chan->channel) {
case PSY_IIO_MMI_OTG_ENABLE:
rc = mmi_discrete_otg_enable(chip, !!val1);
break;
default:
pr_err("Unsupported mmi_discrete 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 mmi_discrete_iio_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val1,
int *val2, long mask)
{
struct mmi_discrete_charger *chip = iio_priv(indio_dev);
int rc = 0;
*val1 = 0;
switch (chan->channel) {
case PSY_IIO_USB_REAL_TYPE:
*val1 = chip->real_charger_type;
break;
default:
pr_err("Unsupported mmi_discrete 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 mmi_discrete_iio_of_xlate(struct iio_dev *indio_dev,
const struct of_phandle_args *iiospec)
{
struct mmi_discrete_charger *chip = iio_priv(indio_dev);
struct iio_chan_spec *iio_chan = chip->iio_chan;
int i;
for (i = 0; i < ARRAY_SIZE(mmi_discrete_iio_psy_channels);
i++, iio_chan++)
if (iio_chan->channel == iiospec->args[0])
return i;
return -EINVAL;
}
static const struct iio_info mmi_discrete_iio_info = {
.read_raw = mmi_discrete_iio_read_raw,
.write_raw = mmi_discrete_iio_write_raw,
.of_xlate = mmi_discrete_iio_of_xlate,
};
int mmi_discrete_init_iio_psy(struct mmi_discrete_charger *chip,
struct platform_device *pdev)
{
struct iio_dev *indio_dev = chip->indio_dev;
struct iio_chan_spec *chan;
int mmi_discrete_num_iio_channels = ARRAY_SIZE(mmi_discrete_iio_psy_channels);
int rc, i;
chip->iio_chan = devm_kcalloc(chip->dev, mmi_discrete_num_iio_channels,
sizeof(*chip->iio_chan), GFP_KERNEL);
if (!chip->iio_chan)
return -ENOMEM;
chip->int_iio_chans = devm_kcalloc(chip->dev,
mmi_discrete_num_iio_channels,
sizeof(*chip->int_iio_chans),
GFP_KERNEL);
if (!chip->int_iio_chans)
return -ENOMEM;
indio_dev->info = &mmi_discrete_iio_info;
indio_dev->dev.parent = chip->dev;
indio_dev->dev.of_node = chip->dev->of_node;
indio_dev->name = "mmi-discrete-iio";
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = chip->iio_chan;
indio_dev->num_channels = mmi_discrete_num_iio_channels;
for (i = 0; i < mmi_discrete_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 = mmi_discrete_iio_psy_channels[i].channel_num;
chan->type = mmi_discrete_iio_psy_channels[i].type;
chan->datasheet_name =
mmi_discrete_iio_psy_channels[i].datasheet_name;
chan->extend_name =
mmi_discrete_iio_psy_channels[i].datasheet_name;
chan->info_mask_separate =
mmi_discrete_iio_psy_channels[i].info_mask;
}
rc = devm_iio_device_register(chip->dev, indio_dev);
if (rc) {
pr_err("Failed to register mmi-discrete-iio IIO device, rc=%d\n", rc);
return rc;
}
return rc;
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2020 Motorola Mobility LLC
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MMI_DISCRETE_CHARGER_IIO_H__
#define __MMI_DISCRETE_CHARGER_IIO_H__
#include <linux/platform_device.h>
#include <linux/iio/consumer.h>
#include <linux/iio/iio.h>
#include <dt-bindings/iio/qti_power_supply_iio.h>
#include "mmi_discrete_charger_core.h"
struct mmi_discrete_iio_channels {
const char *datasheet_name;
int channel_num;
enum iio_chan_type type;
long info_mask;
};
#define MMI_DISCRETE_IIO_CHAN(_name, _num, _type, _mask) \
{ \
.datasheet_name = _name, \
.channel_num = _num, \
.type = _type, \
.info_mask = _mask, \
},
#define MMI_DISCRETE_CHAN_INDEX(_name, _num) \
MMI_DISCRETE_IIO_CHAN(_name, _num, IIO_INDEX, \
BIT(IIO_CHAN_INFO_PROCESSED))
static const struct mmi_discrete_iio_channels mmi_discrete_iio_psy_channels[] = {
MMI_DISCRETE_CHAN_INDEX("usb_real_type", PSY_IIO_USB_REAL_TYPE)
MMI_DISCRETE_CHAN_INDEX("otg_enable", PSY_IIO_MMI_OTG_ENABLE)
};
int mmi_discrete_init_iio_psy(struct mmi_discrete_charger *chip,
struct platform_device *pdev);
#endif