w83627hf.c
来自「linux 内核源代码」· C语言 代码 · 共 1,707 行 · 第 1/4 页
C
1,707 行
(w83627hf_read_value(data, W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); } else { data->pwm[nr] = PWM_TO_REG(val); w83627hf_write_value(data, W836X7HF_REG_PWM(data->type, nr), data->pwm[nr]); } mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0);static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1);static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2);static ssize_tshow_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf){ int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = w83627hf_update_device(dev); if (data->type == w83627hf) return sprintf(buf, "%ld\n", pwm_freq_from_reg_627hf(data->pwm_freq[nr])); else return sprintf(buf, "%ld\n", pwm_freq_from_reg(data->pwm_freq[nr]));}static ssize_tstore_pwm_freq(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count){ int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); static const u8 mask[]={0xF8, 0x8F}; u32 val; val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); if (data->type == w83627hf) { data->pwm_freq[nr] = pwm_freq_to_reg_627hf(val); w83627hf_write_value(data, W83627HF_REG_PWM_FREQ, (data->pwm_freq[nr] << (nr*4)) | (w83627hf_read_value(data, W83627HF_REG_PWM_FREQ) & mask[nr])); } else { data->pwm_freq[nr] = pwm_freq_to_reg(val); w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr], data->pwm_freq[nr]); } mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO|S_IWUSR, show_pwm_freq, store_pwm_freq, 0);static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO|S_IWUSR, show_pwm_freq, store_pwm_freq, 1);static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO|S_IWUSR, show_pwm_freq, store_pwm_freq, 2);static ssize_tshow_temp_type(struct device *dev, struct device_attribute *devattr, char *buf){ int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = w83627hf_update_device(dev); return sprintf(buf, "%ld\n", (long) data->sens[nr]);}static ssize_tstore_temp_type(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count){ int nr = to_sensor_dev_attr(devattr)->index; struct w83627hf_data *data = dev_get_drvdata(dev); u32 val, tmp; val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); switch (val) { case 1: /* PII/Celeron diode */ tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); w83627hf_write_value(data, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr]); tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); w83627hf_write_value(data, W83781D_REG_SCFG2, tmp | BIT_SCFG2[nr]); data->sens[nr] = val; break; case 2: /* 3904 */ tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); w83627hf_write_value(data, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr]); tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); w83627hf_write_value(data, W83781D_REG_SCFG2, tmp & ~BIT_SCFG2[nr]); data->sens[nr] = val; break; case W83781D_DEFAULT_BETA: dev_warn(dev, "Sensor type %d is deprecated, please use 4 " "instead\n", W83781D_DEFAULT_BETA); /* fall through */ case 4: /* thermistor */ tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); w83627hf_write_value(data, W83781D_REG_SCFG1, tmp & ~BIT_SCFG1[nr]); data->sens[nr] = val; break; default: dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or 4\n", (long) val); break; } mutex_unlock(&data->update_lock); return count;}#define sysfs_temp_type(offset) \static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ show_temp_type, store_temp_type, offset - 1);sysfs_temp_type(1);sysfs_temp_type(2);sysfs_temp_type(3);static ssize_tshow_name(struct device *dev, struct device_attribute *devattr, char *buf){ struct w83627hf_data *data = dev_get_drvdata(dev); return sprintf(buf, "%s\n", data->name);}static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);static int __init w83627hf_find(int sioaddr, unsigned short *addr, struct w83627hf_sio_data *sio_data){ int err = -ENODEV; u16 val; static const __initdata char *names[] = { "W83627HF", "W83627THF", "W83697HF", "W83637HF", "W83687THF", }; REG = sioaddr; VAL = sioaddr + 1; superio_enter(); val= superio_inb(DEVID); switch (val) { case W627_DEVID: sio_data->type = w83627hf; break; case W627THF_DEVID: sio_data->type = w83627thf; break; case W697_DEVID: sio_data->type = w83697hf; break; case W637_DEVID: sio_data->type = w83637hf; break; case W687THF_DEVID: sio_data->type = w83687thf; break; case 0xff: /* No device at all */ goto exit; default: pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val); goto exit; } superio_select(W83627HF_LD_HWM); force_addr &= WINB_ALIGNMENT; if (force_addr) { printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n", force_addr); superio_outb(WINB_BASE_REG, force_addr >> 8); superio_outb(WINB_BASE_REG + 1, force_addr & 0xff); } val = (superio_inb(WINB_BASE_REG) << 8) | superio_inb(WINB_BASE_REG + 1); *addr = val & WINB_ALIGNMENT; if (*addr == 0) { printk(KERN_WARNING DRVNAME ": Base address not set, " "skipping\n"); goto exit; } val = superio_inb(WINB_ACT_REG); if (!(val & 0x01)) { printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n"); superio_outb(WINB_ACT_REG, val | 0x01); } err = 0; pr_info(DRVNAME ": Found %s chip at %#x\n", names[sio_data->type], *addr); exit: superio_exit(); return err;}#define VIN_UNIT_ATTRS(_X_) \ &sensor_dev_attr_in##_X_##_input.dev_attr.attr, \ &sensor_dev_attr_in##_X_##_min.dev_attr.attr, \ &sensor_dev_attr_in##_X_##_max.dev_attr.attr#define FAN_UNIT_ATTRS(_X_) \ &sensor_dev_attr_fan##_X_##_input.dev_attr.attr, \ &sensor_dev_attr_fan##_X_##_min.dev_attr.attr, \ &sensor_dev_attr_fan##_X_##_div.dev_attr.attr#define TEMP_UNIT_ATTRS(_X_) \ &sensor_dev_attr_temp##_X_##_input.dev_attr.attr, \ &sensor_dev_attr_temp##_X_##_max.dev_attr.attr, \ &sensor_dev_attr_temp##_X_##_max_hyst.dev_attr.attr, \ &sensor_dev_attr_temp##_X_##_type.dev_attr.attrstatic struct attribute *w83627hf_attributes[] = { &dev_attr_in0_input.attr, &dev_attr_in0_min.attr, &dev_attr_in0_max.attr, VIN_UNIT_ATTRS(2), VIN_UNIT_ATTRS(3), VIN_UNIT_ATTRS(4), VIN_UNIT_ATTRS(7), VIN_UNIT_ATTRS(8), FAN_UNIT_ATTRS(1), FAN_UNIT_ATTRS(2), TEMP_UNIT_ATTRS(1), TEMP_UNIT_ATTRS(2), &dev_attr_alarms.attr, &dev_attr_beep_enable.attr, &dev_attr_beep_mask.attr, &sensor_dev_attr_pwm1.dev_attr.attr, &sensor_dev_attr_pwm2.dev_attr.attr, &dev_attr_name.attr, NULL};static const struct attribute_group w83627hf_group = { .attrs = w83627hf_attributes,};static struct attribute *w83627hf_attributes_opt[] = { VIN_UNIT_ATTRS(1), VIN_UNIT_ATTRS(5), VIN_UNIT_ATTRS(6), FAN_UNIT_ATTRS(3), TEMP_UNIT_ATTRS(3), &sensor_dev_attr_pwm3.dev_attr.attr, &sensor_dev_attr_pwm1_freq.dev_attr.attr, &sensor_dev_attr_pwm2_freq.dev_attr.attr, &sensor_dev_attr_pwm3_freq.dev_attr.attr, NULL};static const struct attribute_group w83627hf_group_opt = { .attrs = w83627hf_attributes_opt,};static int __devinit w83627hf_probe(struct platform_device *pdev){ struct device *dev = &pdev->dev; struct w83627hf_sio_data *sio_data = dev->platform_data; struct w83627hf_data *data; struct resource *res; int err, i; static const char *names[] = { "w83627hf", "w83627thf", "w83697hf", "w83637hf", "w83687thf", }; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) { dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", (unsigned long)res->start, (unsigned long)(res->start + WINB_REGION_SIZE - 1)); err = -EBUSY; goto ERROR0; } if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR1; } data->addr = res->start; data->type = sio_data->type; data->name = names[sio_data->type]; mutex_init(&data->lock); mutex_init(&data->update_lock); platform_set_drvdata(pdev, data); /* Initialize the chip */ w83627hf_init_device(pdev); /* A few vars need to be filled upon startup */ for (i = 0; i <= 2; i++) data->fan_min[i] = w83627hf_read_value( data, W83627HF_REG_FAN_MIN(i)); w83627hf_update_fan_div(data); /* Register common device attributes */ if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group))) goto ERROR3; /* Register chip-specific device attributes */ if (data->type == w83627hf || data->type == w83697hf) if ((err = device_create_file(dev, &sensor_dev_attr_in5_input.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_in5_min.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_in5_max.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_in6_input.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_in6_min.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_in6_max.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_pwm1_freq.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_pwm2_freq.dev_attr))) goto ERROR4; if (data->type != w83697hf) if ((err = device_create_file(dev, &sensor_dev_attr_in1_input.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_in1_min.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_in1_max.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_fan3_input.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_fan3_min.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_fan3_div.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_temp3_input.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_temp3_max.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_temp3_max_hyst.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_temp3_type.dev_attr))) goto ERROR4; if (data->type != w83697hf && data->vid != 0xff) { /* Convert VID to voltage based on VRM */ data->vrm = vid_which_vrm(); if ((err = device_create_file(dev, &dev_attr_cpu0_vid)) || (err = device_create_file(dev, &dev_attr_vrm))) goto ERROR4; } if (data->type == w83627thf || data->type == w83637hf || data->type == w83687thf) if ((err = device_create_file(dev, &sensor_dev_attr_pwm3.dev_attr))) goto ERROR4; if (data->type == w83637hf || data->type == w83687thf) if ((err = device_create_file(dev, &sensor_dev_attr_pwm1_freq.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_pwm2_freq.dev_attr)) || (err = device_create_file(dev, &sensor_dev_attr_pwm3_freq.dev_attr))) goto ERROR4; data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto ERROR4; } return 0; ERROR4: sysfs_remove_group(&dev->kobj, &w83627hf_group); sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); ERROR3: platform_set_drvdata(pdev, NULL); kfree(data); ERROR1: release_region(res->start, WINB_REGION_SIZE); ERROR0: return err;}static int __devexit w83627hf_remove(struct platform_device *pdev){ struct w83627hf_data *data = platform_get_drvdata(pdev); struct resource *res; hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?