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))); 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()
252 struct device_node *fan; in gsc_hwmon_get_devtree_pdata() local
257 return ERR_PTR(-ENODEV); in gsc_hwmon_get_devtree_pdata()
262 return ERR_PTR(-ENOMEM); in gsc_hwmon_get_devtree_pdata()
263 pdata->nchannels = nchannels; in gsc_hwmon_get_devtree_pdata()
265 /* fan controller base address */ in gsc_hwmon_get_devtree_pdata()
266 of_node_get(dev->parent->of_node); in gsc_hwmon_get_devtree_pdata()
267 fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan"); in gsc_hwmon_get_devtree_pdata()
268 if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) { in gsc_hwmon_get_devtree_pdata()
269 of_node_put(fan); in gsc_hwmon_get_devtree_pdata()
270 dev_err(dev, "fan node without base\n"); in gsc_hwmon_get_devtree_pdata()
271 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
274 of_node_put(fan); in gsc_hwmon_get_devtree_pdata()
276 ch = pdata->channels; in gsc_hwmon_get_devtree_pdata()
279 if (fwnode_property_read_string(child, "label", &ch->name)) { in gsc_hwmon_get_devtree_pdata()
281 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
283 if (fwnode_property_read_u32(child, "reg", &ch->reg)) { in gsc_hwmon_get_devtree_pdata()
285 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
287 if (fwnode_property_read_u32(child, "gw,mode", &ch->mode)) { in gsc_hwmon_get_devtree_pdata()
289 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
291 if (ch->mode > mode_max) { in gsc_hwmon_get_devtree_pdata()
293 return ERR_PTR(-EINVAL); in gsc_hwmon_get_devtree_pdata()
297 "gw,voltage-offset-microvolt", in gsc_hwmon_get_devtree_pdata()
298 &ch->mvoffset)) in gsc_hwmon_get_devtree_pdata()
299 ch->mvoffset /= 1000; in gsc_hwmon_get_devtree_pdata()
301 "gw,voltage-divider-ohms", in gsc_hwmon_get_devtree_pdata()
302 ch->vdiv, ARRAY_SIZE(ch->vdiv)); in gsc_hwmon_get_devtree_pdata()
311 struct gsc_dev *gsc = dev_get_drvdata(pdev->dev.parent); in gsc_hwmon_probe() local
312 struct device *dev = &pdev->dev; in gsc_hwmon_probe()
327 return -ENOMEM; in gsc_hwmon_probe()
328 hwmon->gsc = gsc; in gsc_hwmon_probe()
329 hwmon->pdata = pdata; in gsc_hwmon_probe()
331 hwmon->regmap = devm_regmap_init(dev, &gsc_hwmon_regmap_bus, in gsc_hwmon_probe()
332 gsc->i2c_hwmon, in gsc_hwmon_probe()
334 if (IS_ERR(hwmon->regmap)) in gsc_hwmon_probe()
335 return PTR_ERR(hwmon->regmap); in gsc_hwmon_probe()
337 for (i = 0, i_in = 0, i_temp = 0, i_fan = 0; i < hwmon->pdata->nchannels; i++) { in gsc_hwmon_probe()
338 const struct gsc_hwmon_channel *ch = &pdata->channels[i]; in gsc_hwmon_probe()
340 switch (ch->mode) { in gsc_hwmon_probe()
343 dev_err(gsc->dev, "too many temp channels\n"); in gsc_hwmon_probe()
344 return -EINVAL; in gsc_hwmon_probe()
346 hwmon->temp_ch[i_temp] = ch; in gsc_hwmon_probe()
347 hwmon->temp_config[i_temp] = HWMON_T_INPUT | in gsc_hwmon_probe()
353 dev_err(gsc->dev, "too many fan channels\n"); in gsc_hwmon_probe()
354 return -EINVAL; in gsc_hwmon_probe()
356 hwmon->fan_ch[i_fan] = ch; in gsc_hwmon_probe()
357 hwmon->fan_config[i_fan] = HWMON_F_INPUT | in gsc_hwmon_probe()
365 dev_err(gsc->dev, "too many input channels\n"); in gsc_hwmon_probe()
366 return -EINVAL; in gsc_hwmon_probe()
368 hwmon->in_ch[i_in] = ch; in gsc_hwmon_probe()
369 hwmon->in_config[i_in] = in gsc_hwmon_probe()
374 dev_err(gsc->dev, "invalid mode: %d\n", ch->mode); in gsc_hwmon_probe()
375 return -EINVAL; in gsc_hwmon_probe()
380 hwmon->chip.ops = &gsc_hwmon_ops; in gsc_hwmon_probe()
381 hwmon->chip.info = hwmon->info; in gsc_hwmon_probe()
382 hwmon->info[0] = &hwmon->temp_info; in gsc_hwmon_probe()
383 hwmon->info[1] = &hwmon->in_info; in gsc_hwmon_probe()
384 hwmon->info[2] = &hwmon->fan_info; in gsc_hwmon_probe()
385 hwmon->temp_info.type = hwmon_temp; in gsc_hwmon_probe()
386 hwmon->temp_info.config = hwmon->temp_config; in gsc_hwmon_probe()
387 hwmon->in_info.type = hwmon_in; in gsc_hwmon_probe()
388 hwmon->in_info.config = hwmon->in_config; in gsc_hwmon_probe()
389 hwmon->fan_info.type = hwmon_fan; in gsc_hwmon_probe()
390 hwmon->fan_info.config = hwmon->fan_config; in gsc_hwmon_probe()
392 groups = pdata->fan_base ? gsc_hwmon_groups : NULL; in gsc_hwmon_probe()
395 &hwmon->chip, groups); in gsc_hwmon_probe()
400 { .compatible = "gw,gsc-adc", },
407 .name = "gsc-hwmon",
416 MODULE_DESCRIPTION("GSC hardware monitor driver");