Lines Matching +full:address +full:- +full:address +full:- +full:data
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * lm78.c - Part of lm_sensors, Linux kernel modules for hardware
17 #include <linux/hwmon-vid.h>
18 #include <linux/hwmon-sysfs.h>
35 /* Length of ISA address segment */
38 /* Where are the ISA address/data registers relative to the base address */
90 return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div); in FAN_FROM_REG()
94 * TEMP: mC (-128C to +127C)
99 int nval = clamp_val(val, -128000, 127000) ; in TEMP_TO_REG()
100 return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000; in TEMP_TO_REG()
136 static int lm78_read_value(struct lm78_data *data, u8 reg);
137 static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value);
139 static void lm78_init_device(struct lm78_data *data);
146 struct lm78_data *data = lm78_update_device(dev); in in_show() local
147 return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index])); in in_show()
154 struct lm78_data *data = lm78_update_device(dev); in in_min_show() local
155 return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index])); in in_min_show()
162 struct lm78_data *data = lm78_update_device(dev); in in_max_show() local
163 return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index])); in in_max_show()
170 struct lm78_data *data = dev_get_drvdata(dev); in in_min_store() local
171 int nr = attr->index; in in_min_store()
179 mutex_lock(&data->update_lock); in in_min_store()
180 data->in_min[nr] = IN_TO_REG(val); in in_min_store()
181 lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]); in in_min_store()
182 mutex_unlock(&data->update_lock); in in_min_store()
190 struct lm78_data *data = dev_get_drvdata(dev); in in_max_store() local
191 int nr = attr->index; in in_max_store()
199 mutex_lock(&data->update_lock); in in_max_store()
200 data->in_max[nr] = IN_TO_REG(val); in in_max_store()
201 lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]); in in_max_store()
202 mutex_unlock(&data->update_lock); in in_max_store()
232 struct lm78_data *data = lm78_update_device(dev); in temp1_input_show() local
233 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp)); in temp1_input_show()
239 struct lm78_data *data = lm78_update_device(dev); in temp1_max_show() local
240 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over)); in temp1_max_show()
247 struct lm78_data *data = dev_get_drvdata(dev); in temp1_max_store() local
255 mutex_lock(&data->update_lock); in temp1_max_store()
256 data->temp_over = TEMP_TO_REG(val); in temp1_max_store()
257 lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over); in temp1_max_store()
258 mutex_unlock(&data->update_lock); in temp1_max_store()
265 struct lm78_data *data = lm78_update_device(dev); in temp1_max_hyst_show() local
266 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst)); in temp1_max_hyst_show()
273 struct lm78_data *data = dev_get_drvdata(dev); in temp1_max_hyst_store() local
281 mutex_lock(&data->update_lock); in temp1_max_hyst_store()
282 data->temp_hyst = TEMP_TO_REG(val); in temp1_max_hyst_store()
283 lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst); in temp1_max_hyst_store()
284 mutex_unlock(&data->update_lock); in temp1_max_hyst_store()
297 struct lm78_data *data = lm78_update_device(dev); in fan_show() local
298 int nr = attr->index; in fan_show()
299 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], in fan_show()
300 DIV_FROM_REG(data->fan_div[nr]))); in fan_show()
307 struct lm78_data *data = lm78_update_device(dev); in fan_min_show() local
308 int nr = attr->index; in fan_min_show()
309 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr], in fan_min_show()
310 DIV_FROM_REG(data->fan_div[nr]))); in fan_min_show()
317 struct lm78_data *data = dev_get_drvdata(dev); in fan_min_store() local
318 int nr = attr->index; in fan_min_store()
326 mutex_lock(&data->update_lock); in fan_min_store()
327 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); in fan_min_store()
328 lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); in fan_min_store()
329 mutex_unlock(&data->update_lock); in fan_min_store()
337 struct lm78_data *data = lm78_update_device(dev); in fan_div_show() local
338 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); in fan_div_show()
351 struct lm78_data *data = dev_get_drvdata(dev); in fan_div_store() local
352 int nr = attr->index; in fan_div_store()
362 mutex_lock(&data->update_lock); in fan_div_store()
363 min = FAN_FROM_REG(data->fan_min[nr], in fan_div_store()
364 DIV_FROM_REG(data->fan_div[nr])); in fan_div_store()
368 data->fan_div[nr] = 0; in fan_div_store()
371 data->fan_div[nr] = 1; in fan_div_store()
374 data->fan_div[nr] = 2; in fan_div_store()
377 data->fan_div[nr] = 3; in fan_div_store()
383 mutex_unlock(&data->update_lock); in fan_div_store()
384 return -EINVAL; in fan_div_store()
387 reg = lm78_read_value(data, LM78_REG_VID_FANDIV); in fan_div_store()
390 reg = (reg & 0xcf) | (data->fan_div[nr] << 4); in fan_div_store()
393 reg = (reg & 0x3f) | (data->fan_div[nr] << 6); in fan_div_store()
396 lm78_write_value(data, LM78_REG_VID_FANDIV, reg); in fan_div_store()
398 data->fan_min[nr] = in fan_div_store()
399 FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); in fan_div_store()
400 lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); in fan_div_store()
401 mutex_unlock(&data->update_lock); in fan_div_store()
422 struct lm78_data *data = lm78_update_device(dev); in cpu0_vid_show() local
423 return sprintf(buf, "%d\n", vid_from_reg(data->vid, 82)); in cpu0_vid_show()
431 struct lm78_data *data = lm78_update_device(dev); in alarms_show() local
432 return sprintf(buf, "%u\n", data->alarms); in alarms_show()
439 struct lm78_data *data = lm78_update_device(dev); in alarm_show() local
440 int nr = to_sensor_dev_attr(da)->index; in alarm_show()
441 return sprintf(buf, "%u\n", (data->alarms >> nr) & 1); in alarm_show()
533 if (lm78_read_value(isa, LM78_REG_I2C_ADDR) != client->addr) in lm78_alias_detect()
534 return 0; /* Address doesn't match */ in lm78_alias_detect()
577 struct i2c_adapter *adapter = client->adapter; in lm78_i2c_detect()
578 int address = client->addr; in lm78_i2c_detect() local
581 return -ENODEV; in lm78_i2c_detect()
589 mutex_lock(&isa->update_lock); in lm78_i2c_detect()
592 || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR) != address) in lm78_i2c_detect()
603 || i == 0x40) /* LM78-J */ in lm78_i2c_detect()
611 dev_dbg(&adapter->dev, in lm78_i2c_detect()
613 address); in lm78_i2c_detect()
618 mutex_unlock(&isa->update_lock); in lm78_i2c_detect()
620 strscpy(info->type, client_name, I2C_NAME_SIZE); in lm78_i2c_detect()
626 mutex_unlock(&isa->update_lock); in lm78_i2c_detect()
627 return -ENODEV; in lm78_i2c_detect()
632 struct device *dev = &client->dev; in lm78_i2c_probe()
634 struct lm78_data *data; in lm78_i2c_probe() local
636 data = devm_kzalloc(dev, sizeof(struct lm78_data), GFP_KERNEL); in lm78_i2c_probe()
637 if (!data) in lm78_i2c_probe()
638 return -ENOMEM; in lm78_i2c_probe()
640 data->client = client; in lm78_i2c_probe()
641 data->type = (uintptr_t)i2c_get_match_data(client); in lm78_i2c_probe()
644 lm78_init_device(data); in lm78_i2c_probe()
646 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, in lm78_i2c_probe()
647 data, lm78_groups); in lm78_i2c_probe()
673 * We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
676 static int lm78_read_value(struct lm78_data *data, u8 reg) in lm78_read_value() argument
678 struct i2c_client *client = data->client; in lm78_read_value()
683 mutex_lock(&data->lock); in lm78_read_value()
684 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET); in lm78_read_value()
685 res = inb_p(data->isa_addr + LM78_DATA_REG_OFFSET); in lm78_read_value()
686 mutex_unlock(&data->lock); in lm78_read_value()
693 static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) in lm78_write_value() argument
695 struct i2c_client *client = data->client; in lm78_write_value()
699 mutex_lock(&data->lock); in lm78_write_value()
700 outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET); in lm78_write_value()
701 outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET); in lm78_write_value()
702 mutex_unlock(&data->lock); in lm78_write_value()
709 static void lm78_init_device(struct lm78_data *data) in lm78_init_device() argument
715 config = lm78_read_value(data, LM78_REG_CONFIG); in lm78_init_device()
717 lm78_write_value(data, LM78_REG_CONFIG, in lm78_init_device()
722 data->fan_min[i] = lm78_read_value(data, in lm78_init_device()
726 mutex_init(&data->update_lock); in lm78_init_device()
731 struct lm78_data *data = dev_get_drvdata(dev); in lm78_update_device() local
734 mutex_lock(&data->update_lock); in lm78_update_device()
736 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) in lm78_update_device()
737 || !data->valid) { in lm78_update_device()
742 data->in[i] = in lm78_update_device()
743 lm78_read_value(data, LM78_REG_IN(i)); in lm78_update_device()
744 data->in_min[i] = in lm78_update_device()
745 lm78_read_value(data, LM78_REG_IN_MIN(i)); in lm78_update_device()
746 data->in_max[i] = in lm78_update_device()
747 lm78_read_value(data, LM78_REG_IN_MAX(i)); in lm78_update_device()
750 data->fan[i] = in lm78_update_device()
751 lm78_read_value(data, LM78_REG_FAN(i)); in lm78_update_device()
752 data->fan_min[i] = in lm78_update_device()
753 lm78_read_value(data, LM78_REG_FAN_MIN(i)); in lm78_update_device()
755 data->temp = lm78_read_value(data, LM78_REG_TEMP); in lm78_update_device()
756 data->temp_over = in lm78_update_device()
757 lm78_read_value(data, LM78_REG_TEMP_OVER); in lm78_update_device()
758 data->temp_hyst = in lm78_update_device()
759 lm78_read_value(data, LM78_REG_TEMP_HYST); in lm78_update_device()
760 i = lm78_read_value(data, LM78_REG_VID_FANDIV); in lm78_update_device()
761 data->vid = i & 0x0f; in lm78_update_device()
762 if (data->type == lm79) in lm78_update_device()
763 data->vid |= in lm78_update_device()
764 (lm78_read_value(data, LM78_REG_CHIPID) & in lm78_update_device()
767 data->vid |= 0x10; in lm78_update_device()
768 data->fan_div[0] = (i >> 4) & 0x03; in lm78_update_device()
769 data->fan_div[1] = i >> 6; in lm78_update_device()
770 data->alarms = lm78_read_value(data, LM78_REG_ALARM1) + in lm78_update_device()
771 (lm78_read_value(data, LM78_REG_ALARM2) << 8); in lm78_update_device()
772 data->last_updated = jiffies; in lm78_update_device()
773 data->valid = true; in lm78_update_device()
775 data->fan_div[2] = 1; in lm78_update_device()
778 mutex_unlock(&data->update_lock); in lm78_update_device()
780 return data; in lm78_update_device()
786 struct device *dev = &pdev->dev; in lm78_isa_probe()
788 struct lm78_data *data; in lm78_isa_probe() local
793 if (!devm_request_region(dev, res->start + LM78_ADDR_REG_OFFSET, in lm78_isa_probe()
795 return -EBUSY; in lm78_isa_probe()
797 data = devm_kzalloc(dev, sizeof(struct lm78_data), GFP_KERNEL); in lm78_isa_probe()
798 if (!data) in lm78_isa_probe()
799 return -ENOMEM; in lm78_isa_probe()
801 mutex_init(&data->lock); in lm78_isa_probe()
802 data->isa_addr = res->start; in lm78_isa_probe()
803 platform_set_drvdata(pdev, data); in lm78_isa_probe()
805 if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) { in lm78_isa_probe()
806 data->type = lm79; in lm78_isa_probe()
807 data->name = "lm79"; in lm78_isa_probe()
809 data->type = lm78; in lm78_isa_probe()
810 data->name = "lm78"; in lm78_isa_probe()
814 lm78_init_device(data); in lm78_isa_probe()
816 hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name, in lm78_isa_probe()
817 data, lm78_groups); in lm78_isa_probe()
829 static int __init lm78_isa_found(unsigned short address) in lm78_isa_found() argument
839 for (port = address; port < address + LM78_EXTENT; port++) { in lm78_isa_found()
848 * We need the timeouts for at least some LM78-like in lm78_isa_found()
851 val = inb_p(address + 1); in lm78_isa_found()
852 if (inb_p(address + 2) != val in lm78_isa_found()
853 || inb_p(address + 3) != val in lm78_isa_found()
854 || inb_p(address + 7) != val) in lm78_isa_found()
859 * We should be able to change the 7 LSB of the address port. The in lm78_isa_found()
862 save = inb_p(address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
866 outb_p(val, address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
867 if (inb_p(address + LM78_ADDR_REG_OFFSET) != (val | 0x80)) { in lm78_isa_found()
868 outb_p(save, address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
873 outb_p(LM78_REG_CONFIG, address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
874 val = inb_p(address + LM78_DATA_REG_OFFSET); in lm78_isa_found()
877 outb_p(LM78_REG_I2C_ADDR, address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
878 val = inb_p(address + LM78_DATA_REG_OFFSET); in lm78_isa_found()
879 if (val < 0x03 || val > 0x77) /* Not a valid I2C address */ in lm78_isa_found()
883 if (inb_p(address + LM78_ADDR_REG_OFFSET) & 0x80) in lm78_isa_found()
887 outb_p(0x4f, address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
888 val = inb_p(address + LM78_DATA_REG_OFFSET); in lm78_isa_found()
893 outb_p(0x58, address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
894 val = inb_p(address + LM78_DATA_REG_OFFSET); in lm78_isa_found()
899 outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET); in lm78_isa_found()
900 val = inb_p(address + LM78_DATA_REG_OFFSET); in lm78_isa_found()
902 || val == 0x40 /* LM78-J */ in lm78_isa_found()
908 val & 0x80 ? "LM79" : "LM78", (int)address); in lm78_isa_found()
911 for (port--; port >= address; port--) in lm78_isa_found()
916 static int __init lm78_isa_device_add(unsigned short address) in lm78_isa_device_add() argument
919 .start = address, in lm78_isa_device_add()
920 .end = address + LM78_EXTENT - 1, in lm78_isa_device_add()
926 pdev = platform_device_alloc("lm78", address); in lm78_isa_device_add()
928 err = -ENOMEM; in lm78_isa_device_add()