brintos

brintos / linux-shallow public Read only

0
0
Text · 4.2 KiB · f206a9c Raw
176 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * tps65910.c  --  TI TPS6591x4 *5 * Copyright 2010 Texas Instruments Inc.6 *7 * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/init.h>13#include <linux/slab.h>14#include <linux/err.h>15#include <linux/platform_device.h>16#include <linux/debugfs.h>17#include <linux/gpio.h>18#include <linux/mfd/tps65910.h>19 20#define COMP1					021#define COMP2					122 23/* Comparator 1 voltage selection table in millivolts */24static const u16 COMP_VSEL_TABLE[] = {25	0, 2500, 2500, 2500, 2500, 2550, 2600, 2650,26	2700, 2750, 2800, 2850, 2900, 2950, 3000, 3050,27	3100, 3150, 3200, 3250, 3300, 3350, 3400, 3450,28	3500,29};30 31struct comparator {32	const char *name;33	int reg;34	int uV_max;35	const u16 *vsel_table;36};37 38static struct comparator tps_comparators[] = {39	{40		.name = "COMP1",41		.reg = TPS65911_VMBCH,42		.uV_max = 3500,43		.vsel_table = COMP_VSEL_TABLE,44	},45	{46		.name = "COMP2",47		.reg = TPS65911_VMBCH2,48		.uV_max = 3500,49		.vsel_table = COMP_VSEL_TABLE,50	},51};52 53static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)54{55	struct comparator tps_comp = tps_comparators[id];56	int curr_voltage = 0;57	int ret;58	u8 index = 0, val;59 60	while (curr_voltage < tps_comp.uV_max) {61		curr_voltage = tps_comp.vsel_table[index];62		if (curr_voltage >= voltage)63			break;64		else if (curr_voltage < voltage)65			index ++;66	}67 68	if (curr_voltage > tps_comp.uV_max)69		return -EINVAL;70 71	val = index << 1;72	ret = regmap_write(tps65910->regmap, tps_comp.reg, val);73 74	return ret;75}76 77static int comp_threshold_get(struct tps65910 *tps65910, int id)78{79	struct comparator tps_comp = tps_comparators[id];80	unsigned int val;81	int ret;82 83	ret = regmap_read(tps65910->regmap, tps_comp.reg, &val);84	if (ret < 0)85		return ret;86 87	val >>= 1;88	return tps_comp.vsel_table[val];89}90 91static ssize_t comp_threshold_show(struct device *dev,92				struct device_attribute *attr, char *buf)93{94	struct tps65910 *tps65910 = dev_get_drvdata(dev->parent);95	struct attribute comp_attr = attr->attr;96	int id, uVolt;97 98	if (!strcmp(comp_attr.name, "comp1_threshold"))99		id = COMP1;100	else if (!strcmp(comp_attr.name, "comp2_threshold"))101		id = COMP2;102	else103		return -EINVAL;104 105	uVolt = comp_threshold_get(tps65910, id);106 107	return sprintf(buf, "%d\n", uVolt);108}109 110static DEVICE_ATTR(comp1_threshold, S_IRUGO, comp_threshold_show, NULL);111static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL);112 113static int tps65911_comparator_probe(struct platform_device *pdev)114{115	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);116	struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);117	int ret;118 119	ret = comp_threshold_set(tps65910, COMP1,  pdata->vmbch_threshold);120	if (ret < 0) {121		dev_err(&pdev->dev, "cannot set COMP1 threshold\n");122		return ret;123	}124 125	ret = comp_threshold_set(tps65910, COMP2, pdata->vmbch2_threshold);126	if (ret < 0) {127		dev_err(&pdev->dev, "cannot set COMP2 threshold\n");128		return ret;129	}130 131	/* Create sysfs entry */132	ret = device_create_file(&pdev->dev, &dev_attr_comp1_threshold);133	if (ret < 0)134		dev_err(&pdev->dev, "failed to add COMP1 sysfs file\n");135 136	ret = device_create_file(&pdev->dev, &dev_attr_comp2_threshold);137	if (ret < 0)138		dev_err(&pdev->dev, "failed to add COMP2 sysfs file\n");139 140	return ret;141}142 143static void tps65911_comparator_remove(struct platform_device *pdev)144{145	struct tps65910 *tps65910;146 147	tps65910 = dev_get_drvdata(pdev->dev.parent);148	device_remove_file(&pdev->dev, &dev_attr_comp2_threshold);149	device_remove_file(&pdev->dev, &dev_attr_comp1_threshold);150}151 152static struct platform_driver tps65911_comparator_driver = {153	.driver = {154		.name = "tps65911-comparator",155	},156	.probe = tps65911_comparator_probe,157	.remove_new = tps65911_comparator_remove,158};159 160static int __init tps65911_comparator_init(void)161{162	return platform_driver_register(&tps65911_comparator_driver);163}164subsys_initcall(tps65911_comparator_init);165 166static void __exit tps65911_comparator_exit(void)167{168	platform_driver_unregister(&tps65911_comparator_driver);169}170module_exit(tps65911_comparator_exit);171 172MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>");173MODULE_DESCRIPTION("TPS65911 comparator driver");174MODULE_LICENSE("GPL v2");175MODULE_ALIAS("platform:tps65911-comparator");176