Lines Matching +full:gsc +full:- +full:fan
1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/hwmon-sysfs.h>
9 #include <linux/mfd/gsc.h>
26 struct gsc_dev *gsc; member
59 u8 reg = hwmon->pdata->fan_base + (2 * attr->index); in pwm_auto_point_temp_show()
63 ret = regmap_bulk_read(hwmon->regmap, reg, regs, 2); in pwm_auto_point_temp_show()
77 u8 reg = hwmon->pdata->fan_base + (2 * attr->index); in pwm_auto_point_temp_store()
83 return -EINVAL; in pwm_auto_point_temp_store()
90 err = regmap_bulk_write(hwmon->regmap, reg, regs, 2); in pwm_auto_point_temp_store()
103 return sprintf(buf, "%d\n", 255 * (50 + (attr->index * 10)) / 100); in pwm_auto_point_pwm_show()
157 ch = hwmon->in_ch[channel]; in gsc_hwmon_read()
160 ch = hwmon->temp_ch[channel]; in gsc_hwmon_read()
163 ch = hwmon->fan_ch[channel]; in gsc_hwmon_read()
166 return -EOPNOTSUPP; in gsc_hwmon_read()
169 sz = (ch->mode == mode_voltage_24bit) ? 3 : 2; in gsc_hwmon_read()
170 ret = regmap_bulk_read(hwmon->regmap, ch->reg, buf, sz); in gsc_hwmon_read()
175 while (sz-- > 0) in gsc_hwmon_read()
178 switch (ch->mode) { in gsc_hwmon_read()
181 tmp -= 0xffff; in gsc_hwmon_read()
190 if (ch->vdiv[0] && ch->vdiv[1]) { in gsc_hwmon_read()
191 tmp *= (ch->vdiv[0] + ch->vdiv[1]); in gsc_hwmon_read()
192 tmp /= ch->vdiv[1]; in gsc_hwmon_read()
195 tmp += ch->mvoffset; in gsc_hwmon_read()
219 *buf = hwmon->in_ch[channel]->name; in gsc_hwmon_read_string()
222 *buf = hwmon->temp_ch[channel]->name; in gsc_hwmon_read_string()
225 *buf = hwmon->fan_ch[channel]->name; in gsc_hwmon_read_string()
228 return -ENOTSUPP; in gsc_hwmon_read_string()
253 struct device_node *fan; in gsc_hwmon_get_devtree_pdata() local
258 return ERR_PTR(-ENODEV); in gsc_hwmon_get_devtree_pdata()
264 return ERR_PTR(-ENOMEM); in gsc_hwmon_get_devtree_pdata()
266 pdata->channels = ch; in gsc_hwmon_get_devtree_pdata()
267 pdata->nchannels = nchannels; in gsc_hwmon_get_devtree_pdata()
269 /* fan controller base address */ in gsc_hwmon_get_devtree_pdata()
270 of_node_get(dev->parent->of_node); in gsc_hwmon_get_devtree_pdata()
271 fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan"); in gsc_hwmon_get_devtree_pdata()
272 if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) { in gsc_hwmon_get_devtree_pdata()
273 of_node_put(fan); in gsc_hwmon_get_devtree_pdata()
274 dev_err(dev, "fan node without base\n"); in gsc_hwmon_get_devtree_pdata()
275 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
278 of_node_put(fan); in gsc_hwmon_get_devtree_pdata()
282 if (fwnode_property_read_string(child, "label", &ch->name)) { in gsc_hwmon_get_devtree_pdata()
285 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
287 if (fwnode_property_read_u32(child, "reg", &ch->reg)) { in gsc_hwmon_get_devtree_pdata()
290 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
292 if (fwnode_property_read_u32(child, "gw,mode", &ch->mode)) { in gsc_hwmon_get_devtree_pdata()
295 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
297 if (ch->mode > mode_max) { in gsc_hwmon_get_devtree_pdata()
300 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
304 "gw,voltage-offset-microvolt", in gsc_hwmon_get_devtree_pdata()
305 &ch->mvoffset)) in gsc_hwmon_get_devtree_pdata()
306 ch->mvoffset /= 1000; in gsc_hwmon_get_devtree_pdata()
308 "gw,voltage-divider-ohms", in gsc_hwmon_get_devtree_pdata()
309 ch->vdiv, ARRAY_SIZE(ch->vdiv)); in gsc_hwmon_get_devtree_pdata()
318 struct gsc_dev *gsc = dev_get_drvdata(pdev->dev.parent); in gsc_hwmon_probe() local
319 struct device *dev = &pdev->dev; in gsc_hwmon_probe()
334 return -ENOMEM; in gsc_hwmon_probe()
335 hwmon->gsc = gsc; in gsc_hwmon_probe()
336 hwmon->pdata = pdata; in gsc_hwmon_probe()
338 hwmon->regmap = devm_regmap_init(dev, &gsc_hwmon_regmap_bus, in gsc_hwmon_probe()
339 gsc->i2c_hwmon, in gsc_hwmon_probe()
341 if (IS_ERR(hwmon->regmap)) in gsc_hwmon_probe()
342 return PTR_ERR(hwmon->regmap); in gsc_hwmon_probe()
344 for (i = 0, i_in = 0, i_temp = 0, i_fan = 0; i < hwmon->pdata->nchannels; i++) { in gsc_hwmon_probe()
345 const struct gsc_hwmon_channel *ch = &pdata->channels[i]; in gsc_hwmon_probe()
347 switch (ch->mode) { in gsc_hwmon_probe()
350 dev_err(gsc->dev, "too many temp channels\n"); in gsc_hwmon_probe()
351 return -EINVAL; in gsc_hwmon_probe()
353 hwmon->temp_ch[i_temp] = ch; in gsc_hwmon_probe()
354 hwmon->temp_config[i_temp] = HWMON_T_INPUT | in gsc_hwmon_probe()
360 dev_err(gsc->dev, "too many fan channels\n"); in gsc_hwmon_probe()
361 return -EINVAL; in gsc_hwmon_probe()
363 hwmon->fan_ch[i_fan] = ch; in gsc_hwmon_probe()
364 hwmon->fan_config[i_fan] = HWMON_F_INPUT | in gsc_hwmon_probe()
372 dev_err(gsc->dev, "too many input channels\n"); in gsc_hwmon_probe()
373 return -EINVAL; in gsc_hwmon_probe()
375 hwmon->in_ch[i_in] = ch; in gsc_hwmon_probe()
376 hwmon->in_config[i_in] = in gsc_hwmon_probe()
381 dev_err(gsc->dev, "invalid mode: %d\n", ch->mode); in gsc_hwmon_probe()
382 return -EINVAL; in gsc_hwmon_probe()
387 hwmon->chip.ops = &gsc_hwmon_ops; in gsc_hwmon_probe()
388 hwmon->chip.info = hwmon->info; in gsc_hwmon_probe()
389 hwmon->info[0] = &hwmon->temp_info; in gsc_hwmon_probe()
390 hwmon->info[1] = &hwmon->in_info; in gsc_hwmon_probe()
391 hwmon->info[2] = &hwmon->fan_info; in gsc_hwmon_probe()
392 hwmon->temp_info.type = hwmon_temp; in gsc_hwmon_probe()
393 hwmon->temp_info.config = hwmon->temp_config; in gsc_hwmon_probe()
394 hwmon->in_info.type = hwmon_in; in gsc_hwmon_probe()
395 hwmon->in_info.config = hwmon->in_config; in gsc_hwmon_probe()
396 hwmon->fan_info.type = hwmon_fan; in gsc_hwmon_probe()
397 hwmon->fan_info.config = hwmon->fan_config; in gsc_hwmon_probe()
399 groups = pdata->fan_base ? gsc_hwmon_groups : NULL; in gsc_hwmon_probe()
402 &hwmon->chip, groups); in gsc_hwmon_probe()
407 { .compatible = "gw,gsc-adc", },
413 .name = "gsc-hwmon",
422 MODULE_DESCRIPTION("GSC hardware monitor driver");