1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * tps65910.c -- TI TPS6591x
5 * Copyright 2010 Texas Instruments Inc.
7 * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
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>
23 /* Comparator 1 voltage selection table in millivolts */
24 static 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,
35 const u16
*vsel_table
;
38 static struct comparator tps_comparators
[] = {
41 .reg
= TPS65911_VMBCH
,
43 .vsel_table
= COMP_VSEL_TABLE
,
47 .reg
= TPS65911_VMBCH2
,
49 .vsel_table
= COMP_VSEL_TABLE
,
53 static int comp_threshold_set(struct tps65910
*tps65910
, int id
, int voltage
)
55 struct comparator tps_comp
= tps_comparators
[id
];
60 while (curr_voltage
< tps_comp
.uV_max
) {
61 curr_voltage
= tps_comp
.vsel_table
[index
];
62 if (curr_voltage
>= voltage
)
64 else if (curr_voltage
< voltage
)
68 if (curr_voltage
> tps_comp
.uV_max
)
72 ret
= regmap_write(tps65910
->regmap
, tps_comp
.reg
, val
);
77 static int comp_threshold_get(struct tps65910
*tps65910
, int id
)
79 struct comparator tps_comp
= tps_comparators
[id
];
83 ret
= regmap_read(tps65910
->regmap
, tps_comp
.reg
, &val
);
88 return tps_comp
.vsel_table
[val
];
91 static ssize_t
comp_threshold_show(struct device
*dev
,
92 struct device_attribute
*attr
, char *buf
)
94 struct tps65910
*tps65910
= dev_get_drvdata(dev
->parent
);
95 struct attribute comp_attr
= attr
->attr
;
98 if (!strcmp(comp_attr
.name
, "comp1_threshold"))
100 else if (!strcmp(comp_attr
.name
, "comp2_threshold"))
105 uVolt
= comp_threshold_get(tps65910
, id
);
107 return sprintf(buf
, "%d\n", uVolt
);
110 static DEVICE_ATTR(comp1_threshold
, S_IRUGO
, comp_threshold_show
, NULL
);
111 static DEVICE_ATTR(comp2_threshold
, S_IRUGO
, comp_threshold_show
, NULL
);
113 static int tps65911_comparator_probe(struct platform_device
*pdev
)
115 struct tps65910
*tps65910
= dev_get_drvdata(pdev
->dev
.parent
);
116 struct tps65910_board
*pdata
= dev_get_platdata(tps65910
->dev
);
119 ret
= comp_threshold_set(tps65910
, COMP1
, pdata
->vmbch_threshold
);
121 dev_err(&pdev
->dev
, "cannot set COMP1 threshold\n");
125 ret
= comp_threshold_set(tps65910
, COMP2
, pdata
->vmbch2_threshold
);
127 dev_err(&pdev
->dev
, "cannot set COMP2 threshold\n");
131 /* Create sysfs entry */
132 ret
= device_create_file(&pdev
->dev
, &dev_attr_comp1_threshold
);
134 dev_err(&pdev
->dev
, "failed to add COMP1 sysfs file\n");
136 ret
= device_create_file(&pdev
->dev
, &dev_attr_comp2_threshold
);
138 dev_err(&pdev
->dev
, "failed to add COMP2 sysfs file\n");
143 static void tps65911_comparator_remove(struct platform_device
*pdev
)
145 struct tps65910
*tps65910
;
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
);
152 static struct platform_driver tps65911_comparator_driver
= {
154 .name
= "tps65911-comparator",
156 .probe
= tps65911_comparator_probe
,
157 .remove
= tps65911_comparator_remove
,
160 static int __init
tps65911_comparator_init(void)
162 return platform_driver_register(&tps65911_comparator_driver
);
164 subsys_initcall(tps65911_comparator_init
);
166 static void __exit
tps65911_comparator_exit(void)
168 platform_driver_unregister(&tps65911_comparator_driver
);
170 module_exit(tps65911_comparator_exit
);
172 MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>");
173 MODULE_DESCRIPTION("TPS65911 comparator driver");
174 MODULE_LICENSE("GPL v2");
175 MODULE_ALIAS("platform:tps65911-comparator");