Re: [PATCH V2 5/5] Add support for Awinic sar sensor.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 05/06/2024 11:11, wangshuaijie@xxxxxxxxxx wrote:
> From: shuaijie wang <wangshuaijie@xxxxxxxxxx>
> 
> Signed-off-by: shuaijie wang <wangshuaijie@xxxxxxxxxx>
> | Reported-by: kernel test robot <lkp@xxxxxxxxx>
> | Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
> | Reported-by: Dan Carpenter <error27@xxxxxxxxx>
> ---
>  drivers/input/misc/Kconfig         |    9 +
>  drivers/input/misc/Makefile        |    1 +
>  drivers/input/misc/aw_sar/Makefile |    2 +
>  drivers/input/misc/aw_sar/aw_sar.c | 2036 ++++++++++++++++++++++++++++
>  drivers/input/misc/aw_sar/aw_sar.h |   15 +
>  5 files changed, 2063 insertions(+)
>  create mode 100644 drivers/input/misc/aw_sar/Makefile
>  create mode 100644 drivers/input/misc/aw_sar/aw_sar.c
>  create mode 100644 drivers/input/misc/aw_sar/aw_sar.h
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 6ba984d7f0b1..ac56fdd21839 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -939,4 +939,13 @@ config INPUT_STPMIC1_ONKEY
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called stpmic1_onkey.
>  
> +config AWINIC_SAR
> +	tristate "Awinic sar sensor support"
> +	depends on I2C
> +	help
> +	  Say Y to enable support for the Awinic sar sensor driver.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called awinic_sar.
> +
>  endif
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index 04296a4abe8e..6ee1870ea677 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -90,3 +90,4 @@ obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
>  obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND)	+= xen-kbdfront.o
>  obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
>  obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR)	+= ideapad_slidebar.o
> +obj-$(CONFIG_AWINIC_SAR)		+= aw_sar/
> diff --git a/drivers/input/misc/aw_sar/Makefile b/drivers/input/misc/aw_sar/Makefile
> new file mode 100644
> index 000000000000..c357ecaa4f98
> --- /dev/null
> +++ b/drivers/input/misc/aw_sar/Makefile
> @@ -0,0 +1,2 @@
> +obj-$(CONFIG_AWINIC_SAR) += awinic_sar.o
> +awinic_sar-objs := ./comm/aw_sar_comm_interface.o aw_sar.o ./aw9610x/aw9610x.o ./aw963xx/aw963xx.o
> diff --git a/drivers/input/misc/aw_sar/aw_sar.c b/drivers/input/misc/aw_sar/aw_sar.c
> new file mode 100644
> index 000000000000..ab89fed65a6a
> --- /dev/null
> +++ b/drivers/input/misc/aw_sar/aw_sar.c
> @@ -0,0 +1,2036 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * AWINIC sar sensor driver
> + *
> + * Author: Shuaijie Wang<wangshuaijie@xxxxxxxxxx>
> + *
> + * Copyright (c) 2024 awinic Technology CO., LTD
> + */
> +#include "./comm/aw_sar_chip_interface.h"
> +#include "aw_sar.h"
> +
> +#define AW_SAR_I2C_NAME		"awinic_sar"
> +
> +/*
> + * Please check which power_supply on your platform
> + * can get the charger insertion information, then select it.
> + * eg: "usb"/"charger"/"mtk-master-charger"/"mtk_charger_type"
> + */
> +#define USB_POWER_SUPPLY_NAME   "charger"
> +/*
> + * Check which of your power_supply properties is available
> + * for the charger insertion information and select it.
> + * eg: POWER_SUPPLY_PROP_ONLINE/POWER_SUPPLY_PROP_PRESENT
> + */
> +#define AW_USB_PROP_ONLINE	POWER_SUPPLY_PROP_ONLINE
> +
> +#define AW_I2C_RW_RETRY_TIME_MIN		(2000)
> +#define AW_I2C_RW_RETRY_TIME_MAX		(3000)
> +#define AW_RETRIES				(5)
> +
> +#define AW_SAR_AWRW_OffSET			(20)
> +#define AW_SAR_AWRW_DATA_WIDTH			(5)
> +#define AW_DATA_OffSET_2			(2)
> +#define AW_DATA_OffSET_3			(3)
> +#define AW_POWER_ON_SYSFS_DELAY_MS		(5000)
> +#define AW_SAR_MONITOR_ESD_DELAY_MS		(5000)
> +#define AW_SAR_OFFSET_LEN			(15)
> +#define AW_SAR_VCC_MIN_UV			(1700000)
> +#define AW_SAR_VCC_MAX_UV			(3600000)
> +
> +static struct mutex aw_sar_lock;
> +
> +static int32_t aw_sar_get_chip_info(struct aw_sar *p_sar);
> +static void aw_sar_sensor_free(struct aw_sar *p_sar);
> +
> +//Because disable/enable_irq api Therefore, IRQ is embedded
> +void aw_sar_disable_irq(struct aw_sar *p_sar)
> +{
> +	if (p_sar->irq_init.host_irq_stat == IRQ_ENABLE) {
> +		disable_irq(p_sar->irq_init.to_irq);
> +		p_sar->irq_init.host_irq_stat = IRQ_DISABLE;
> +	}
> +}
> +
> +void aw_sar_enable_irq(struct aw_sar *p_sar)
> +{
> +	if (p_sar->irq_init.host_irq_stat == IRQ_DISABLE) {
> +		enable_irq(p_sar->irq_init.to_irq);
> +		p_sar->irq_init.host_irq_stat = IRQ_ENABLE;
> +	}
> +}
> +
> +//Chip logic part start
> +//Load default array function
> +static int32_t
> +aw_sar_para_loaded_func(struct i2c_client *i2c, const struct aw_sar_para_load_t *para_load)
> +{
> +	int32_t ret;
> +	int32_t i;

int32_t? So you send user-space driver to the kernel? That would explain
this terrible coding style, but it is a clear no-go.


...

> +static void aw_sar_monitor_work(struct work_struct *aw_work)
> +{
> +	struct aw_sar *p_sar = container_of(aw_work, struct aw_sar, monitor_work.work);
> +	uint32_t data;
> +	int32_t ret;
> +
> +	ret = aw_sar_i2c_read(p_sar->i2c, 0x0000, &data);
> +	if (ret != 0) {
> +		dev_err(p_sar->dev, "read 0x0000 err: %d", ret);
> +		return;
> +	}
> +	if (data == 0 && p_sar->driver_code_initover_flag) {
> +		dev_err(p_sar->dev, "aw_chip may reset");
> +		aw_sar_disable_irq(p_sar);
> +		ret = aw_sar_chip_init(p_sar);
> +		if (ret != 0)
> +			return;
> +	}
> +	queue_delayed_work(p_sar->monitor_wq, &p_sar->monitor_work,
> +			msecs_to_jiffies(AW_SAR_MONITOR_ESD_DELAY_MS));
> +}
> +
> +static int32_t aw_sar_monitor_esd_init(struct aw_sar *p_sar)
> +{
> +	p_sar->monitor_wq = create_singlethread_workqueue("aw_sar_workqueue");
> +	if (!p_sar->monitor_wq) {
> +		dev_err(&p_sar->i2c->dev, "aw_sar_workqueue error");
> +		return -EINVAL;
> +	}
> +	INIT_DELAYED_WORK(&p_sar->monitor_work, aw_sar_monitor_work);
> +	queue_delayed_work(p_sar->monitor_wq, &p_sar->monitor_work,
> +			msecs_to_jiffies(AW_SAR_MONITOR_ESD_DELAY_MS));
> +
> +	return 0;
> +}
> +
> +static void aw_sar_sensor_free(struct aw_sar *p_sar)
> +{
> +	if (g_aw_sar_driver_list[p_sar->curr_use_driver_type].p_chip_deinit != NULL)
> +		g_aw_sar_driver_list[p_sar->curr_use_driver_type].p_chip_deinit(p_sar);
> +}
> +
> +
> +/* Drive logic entry */
> +static int32_t aw_sar_i2c_probe(struct i2c_client *i2c)
> +{
> +	struct aw_sar *p_sar;
> +	int32_t ret;
> +
> +	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
> +		pr_err("check_functionality failed!\n");
> +		return -EIO;
> +	}
> +
> +	p_sar = devm_kzalloc(&i2c->dev, sizeof(struct aw_sar), GFP_KERNEL);

Heh, so you upstream 10 year old code?

sizeof(*)

> +	if (!p_sar) {
> +		ret = -ENOMEM;
> +		goto err_malloc;

That's just return.

> +	}
> +
> +	p_sar->dev = &i2c->dev;
> +	p_sar->i2c = i2c;
> +	i2c_set_clientdata(i2c, p_sar);
> +
> +	//1.Judge whether to use regular power supply. If yes, supply power
> +	ret = aw_sar_regulator_power(p_sar);
> +	if (ret != 0) {
> +		dev_err(&i2c->dev, "regulator_power error!");
> +		goto err_malloc;
> +	}
> +
> +	//2.Get chip initialization resources
> +	ret = aw_sar_get_chip_info(p_sar);
> +	if (ret != 0) {
> +		dev_err(&i2c->dev, "chip_init error!");

DON't SCREAM! No need!

> +		goto err_chip_init;
> +	}
> +
> +	//3.Chip initialization process
> +	ret = aw_sar_init(p_sar);
> +	if (ret != 0) {
> +		dev_err(&i2c->dev, "sar_init error!");
> +		goto err_sar_init;
> +	}
> +
> +	if (p_sar->dts_info.monitor_esd_flag) {
> +		ret = aw_sar_monitor_esd_init(p_sar);
> +		if (ret != 0) {
> +			dev_err(&i2c->dev, "monitor_esd_init error!");
> +			goto err_esd_init;
> +		}
> +	}
> +
> +	dev_dbg(&i2c->dev, "probe success!");

No. Drop all silly function entry/exit/success messages.

EVERYWHERE.

> +
> +	return 0;
> +


> +static const struct of_device_id aw_sar_dt_match[] = {
> +	{ .compatible = "awinic,aw96103" },
> +	{ .compatible = "awinic,aw96105" },
> +	{ .compatible = "awinic,aw96303" },
> +	{ .compatible = "awinic,aw96305" },
> +	{ .compatible = "awinic,aw96308" },

So all are compatible... express it in bindings.

> +	{ },
> +};
> +
> +static const struct i2c_device_id aw_sar_i2c_id[] = {
> +	{ AW_SAR_I2C_NAME, 0 },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, aw_sar_i2c_id);
> +
> +static struct i2c_driver aw_sar_i2c_driver = {
> +	.driver = {
> +		.name = AW_SAR_I2C_NAME,
> +		.owner = THIS_MODULE,

NAK

> +		.of_match_table = aw_sar_dt_match,
> +		.pm = &aw_sar_pm_ops,
> +	},
> +	.probe = aw_sar_i2c_probe,
> +	.remove = aw_sar_i2c_remove,
> +	.shutdown = aw_sar_i2c_shutdown,
> +	.id_table = aw_sar_i2c_id,
> +};
> +
> +static int32_t __init aw_sar_i2c_init(void)
> +{
> +	int32_t ret;
> +
> +	ret = i2c_add_driver(&aw_sar_i2c_driver);
> +	if (ret) {
> +		pr_err("fail to add aw_sar device into i2c\n");
> +		return ret;
> +	}

Srsly, this is just NAK. This code is way too poor. Get some internal
help from awinic, because this should not be sent.

> +
> +	return 0;
> +}
> +
> +module_init(aw_sar_i2c_init);
> +static void __exit aw_sar_i2c_exit(void)
> +{
> +	i2c_del_driver(&aw_sar_i2c_driver);
> +}
> +module_exit(aw_sar_i2c_exit);
> +MODULE_DESCRIPTION("AWINIC SAR Driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/input/misc/aw_sar/aw_sar.h b/drivers/input/misc/aw_sar/aw_sar.h
> new file mode 100644
> index 000000000000..7a139f56e9c3
> --- /dev/null
> +++ b/drivers/input/misc/aw_sar/aw_sar.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef AW_SAR_H_
> +#define AW_SAR_H_
> +
> +void aw_sar_disable_irq(struct aw_sar *p_sar);
> +void aw_sar_enable_irq(struct aw_sar *p_sar);
> +
> +int32_t aw_sar_soft_reset(struct aw_sar *p_sar);
> +int32_t aw_sar_check_init_over_irq(struct aw_sar *p_sar);
> +int32_t aw_sar_update_fw(struct aw_sar *p_sar);
> +int32_t aw_sar_load_def_reg_bin(struct aw_sar *p_sar);
> +void aw_sar_mode_set(struct aw_sar *p_sar, uint8_t curr_mode);
> +int32_t aw_sar_update_reg_set_func(struct aw_sar *p_sar);


Why is all this needed for one file and why is it here?

Best regards,
Krzysztof





[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux