• Home
  • Raw
  • Download

Lines Matching +full:adc +full:- +full:sleep +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-only
2 /* linux/drivers/hwmon/s3c-hwmon.c
8 * S3C24XX/S3C64XX ADC hwmon support
21 #include <linux/hwmon-sysfs.h>
23 #include <linux/soc/samsung/s3c-adc.h>
24 #include <linux/platform_data/hwmon-s3c.h>
34 * struct s3c_hwmon - ADC hwmon client information
36 * @client: The client we registered with the S3C ADC core.
49 * s3c_hwmon_read_ch - read a value from a given adc channel.
54 * Read a value from the @channel with the proper locking and sleep until
55 * either the read completes or we timeout awaiting the ADC core to get
63 ret = mutex_lock_interruptible(&hwmon->lock); in s3c_hwmon_read_ch()
69 ret = s3c_adc_read(hwmon->client, channel); in s3c_hwmon_read_ch()
70 mutex_unlock(&hwmon->lock); in s3c_hwmon_read_ch()
77 * s3c_hwmon_show_raw - show a conversion from the raw channel number.
83 * ADC channel. This does a conversion and returns the raw (un-scaled)
89 struct s3c_hwmon *adc = dev_get_drvdata(dev); in s3c_hwmon_show_raw() local
93 ret = s3c_hwmon_read_ch(dev, adc, sa->index); in s3c_hwmon_show_raw()
125 return sysfs_create_group(&dev->kobj, &s3c_hwmon_attrgroup); in s3c_hwmon_add_raw()
130 sysfs_remove_group(&dev->kobj, &s3c_hwmon_attrgroup); in s3c_hwmon_remove_raw()
141 * s3c_hwmon_ch_show - show value of a given channel
146 * Read a value from the ADC and scale it before returning it to the
160 cfg = pdata->in[sen_attr->index]; in s3c_hwmon_ch_show()
162 ret = s3c_hwmon_read_ch(dev, hwmon, sen_attr->index); in s3c_hwmon_ch_show()
166 ret *= cfg->mult; in s3c_hwmon_ch_show()
167 ret = DIV_ROUND_CLOSEST(ret, cfg->div); in s3c_hwmon_ch_show()
173 * s3c_hwmon_label_show - show label name of the given channel.
188 cfg = pdata->in[sen_attr->index]; in s3c_hwmon_label_show()
190 return snprintf(buf, PAGE_SIZE, "%s\n", cfg->name); in s3c_hwmon_label_show()
194 * s3c_hwmon_create_attr - create hwmon attribute for given channel.
197 * @channel: The ADC channel number to process.
215 snprintf(attrs->in_name, sizeof(attrs->in_name), "in%d_input", channel); in s3c_hwmon_create_attr()
217 attr = &attrs->in; in s3c_hwmon_create_attr()
218 attr->index = channel; in s3c_hwmon_create_attr()
219 sysfs_attr_init(&attr->dev_attr.attr); in s3c_hwmon_create_attr()
220 attr->dev_attr.attr.name = attrs->in_name; in s3c_hwmon_create_attr()
221 attr->dev_attr.attr.mode = S_IRUGO; in s3c_hwmon_create_attr()
222 attr->dev_attr.show = s3c_hwmon_ch_show; in s3c_hwmon_create_attr()
224 ret = device_create_file(dev, &attr->dev_attr); in s3c_hwmon_create_attr()
231 if (cfg->name) { in s3c_hwmon_create_attr()
232 snprintf(attrs->label_name, sizeof(attrs->label_name), in s3c_hwmon_create_attr()
235 attr = &attrs->label; in s3c_hwmon_create_attr()
236 attr->index = channel; in s3c_hwmon_create_attr()
237 sysfs_attr_init(&attr->dev_attr.attr); in s3c_hwmon_create_attr()
238 attr->dev_attr.attr.name = attrs->label_name; in s3c_hwmon_create_attr()
239 attr->dev_attr.attr.mode = S_IRUGO; in s3c_hwmon_create_attr()
240 attr->dev_attr.show = s3c_hwmon_label_show; in s3c_hwmon_create_attr()
242 ret = device_create_file(dev, &attr->dev_attr); in s3c_hwmon_create_attr()
244 device_remove_file(dev, &attrs->in.dev_attr); in s3c_hwmon_create_attr()
255 device_remove_file(dev, &attrs->in.dev_attr); in s3c_hwmon_remove_attr()
256 device_remove_file(dev, &attrs->label.dev_attr); in s3c_hwmon_remove_attr()
260 * s3c_hwmon_probe - device probe entry.
265 struct s3c_hwmon_pdata *pdata = dev_get_platdata(&dev->dev); in s3c_hwmon_probe()
271 dev_err(&dev->dev, "no platform data supplied\n"); in s3c_hwmon_probe()
272 return -EINVAL; in s3c_hwmon_probe()
275 hwmon = devm_kzalloc(&dev->dev, sizeof(struct s3c_hwmon), GFP_KERNEL); in s3c_hwmon_probe()
277 return -ENOMEM; in s3c_hwmon_probe()
281 mutex_init(&hwmon->lock); in s3c_hwmon_probe()
283 /* Register with the core ADC driver. */ in s3c_hwmon_probe()
285 hwmon->client = s3c_adc_register(dev, NULL, NULL, 0); in s3c_hwmon_probe()
286 if (IS_ERR(hwmon->client)) { in s3c_hwmon_probe()
287 dev_err(&dev->dev, "cannot register adc\n"); in s3c_hwmon_probe()
288 return PTR_ERR(hwmon->client); in s3c_hwmon_probe()
291 /* add attributes for our adc devices. */ in s3c_hwmon_probe()
293 ret = s3c_hwmon_add_raw(&dev->dev); in s3c_hwmon_probe()
299 hwmon->hwmon_dev = hwmon_device_register(&dev->dev); in s3c_hwmon_probe()
300 if (IS_ERR(hwmon->hwmon_dev)) { in s3c_hwmon_probe()
301 dev_err(&dev->dev, "error registering with hwmon\n"); in s3c_hwmon_probe()
302 ret = PTR_ERR(hwmon->hwmon_dev); in s3c_hwmon_probe()
306 for (i = 0; i < ARRAY_SIZE(pdata->in); i++) { in s3c_hwmon_probe()
307 struct s3c_hwmon_chcfg *cfg = pdata->in[i]; in s3c_hwmon_probe()
312 if (cfg->mult >= 0x10000) in s3c_hwmon_probe()
313 dev_warn(&dev->dev, in s3c_hwmon_probe()
317 if (cfg->div == 0) { in s3c_hwmon_probe()
318 dev_err(&dev->dev, "channel %d divider zero\n", i); in s3c_hwmon_probe()
322 ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i], in s3c_hwmon_probe()
323 &hwmon->attrs[i], i); in s3c_hwmon_probe()
325 dev_err(&dev->dev, in s3c_hwmon_probe()
328 for (i--; i >= 0; i--) in s3c_hwmon_probe()
329 s3c_hwmon_remove_attr(&dev->dev, in s3c_hwmon_probe()
330 &hwmon->attrs[i]); in s3c_hwmon_probe()
339 hwmon_device_unregister(hwmon->hwmon_dev); in s3c_hwmon_probe()
342 s3c_hwmon_remove_raw(&dev->dev); in s3c_hwmon_probe()
345 s3c_adc_release(hwmon->client); in s3c_hwmon_probe()
355 s3c_hwmon_remove_raw(&dev->dev); in s3c_hwmon_remove()
357 for (i = 0; i < ARRAY_SIZE(hwmon->attrs); i++) in s3c_hwmon_remove()
358 s3c_hwmon_remove_attr(&dev->dev, &hwmon->attrs[i]); in s3c_hwmon_remove()
360 hwmon_device_unregister(hwmon->hwmon_dev); in s3c_hwmon_remove()
361 s3c_adc_release(hwmon->client); in s3c_hwmon_remove()
368 .name = "s3c-hwmon",
377 MODULE_DESCRIPTION("S3C ADC HWMon driver");
379 MODULE_ALIAS("platform:s3c-hwmon");