Lines Matching +full:per +full:- +full:mille
1 // SPDX-License-Identifier: GPL-2.0+
3 * cc2.c - Support for the Amphenol ChipCap 2 relative humidity, temperature sensor
11 * https://www.amphenol-sensors.com/en/telaire/humidity/527-humidity-sensors/3095-chipcap-2
58 /* ensure clean off -> on transitions */
97 /* %RH as a per cent mille from a register value */
102 return tmp / ((1 << 14) - 1); in cc2_rh_convert()
108 return data * ((1 << 14) - 1) / CC2_RH_MAX; in cc2_rh_to_reg()
114 unsigned long tmp = ((data >> 2) * 165 * 1000U) / ((1 << 14) - 1); in cc2_temp_convert()
116 return tmp - 40 * 1000U; in cc2_temp_convert()
124 if (regulator_is_enabled(data->regulator)) in cc2_enable()
128 try_wait_for_completion(&data->complete); in cc2_enable()
130 ret = regulator_enable(data->regulator); in cc2_enable()
136 data->process_irqs = true; in cc2_enable()
146 data->process_irqs = false; in cc2_disable()
149 if (regulator_is_enabled(data->regulator)) { in cc2_disable()
150 err = regulator_disable(data->regulator); in cc2_disable()
152 dev_dbg(&data->client->dev, "Failed to disable device"); in cc2_disable()
162 return -ETIMEDOUT; in cc2_cmd_response_diagnostic()
170 return -EBUSY; in cc2_cmd_response_diagnostic()
180 return -ENODATA; in cc2_cmd_response_diagnostic()
183 return -EINVAL; in cc2_cmd_response_diagnostic()
194 ret = ret < 0 ? ret : -EIO; in cc2_read_command_status()
198 return cc2_cmd_response_diagnostic(&client->dev, status); in cc2_read_command_status()
203 * first 10 ms after power-up. Only in case the command window is missed,
216 ret = i2c_smbus_write_word_data(data->client, CC2_START_CM, 0); in cc2_command_mode_start()
220 if (data->irq_ready > 0) { in cc2_command_mode_start()
222 ret = wait_for_completion_timeout(&data->complete, in cc2_command_mode_start()
225 return -ETIMEDOUT; in cc2_command_mode_start()
230 ret = cc2_read_command_status(data->client); in cc2_command_mode_start()
231 if (ret != -ETIMEDOUT || i == CC2_CM_RETRIES) in cc2_command_mode_start()
249 ret = i2c_smbus_write_word_data(data->client, CC2_START_NOM, 0); in cc2_command_mode_finish()
266 ret = i2c_smbus_write_word_data(data->client, reg, val); in cc2_write_reg()
270 if (data->irq_ready > 0) { in cc2_write_reg()
272 ret = wait_for_completion_timeout(&data->complete, timeout); in cc2_write_reg()
274 ret = -ETIMEDOUT; in cc2_write_reg()
281 ret = cc2_read_command_status(data->client); in cc2_write_reg()
299 ret = i2c_smbus_write_word_data(data->client, reg, 0); in cc2_read_reg()
303 if (data->irq_ready > 0) { in cc2_read_reg()
305 ret = wait_for_completion_timeout(&data->complete, timeout); in cc2_read_reg()
307 return -ETIMEDOUT; in cc2_read_reg()
312 ret = i2c_master_recv(data->client, buf, CC2_EEPROM_DATA_LEN); in cc2_read_reg()
314 return ret < 0 ? ret : -EIO; in cc2_read_reg()
318 return cc2_read_command_status(data->client); in cc2_read_reg()
344 ret = ret < 0 ? ret : -EIO; in cc2_data_fetch()
349 return -EBUSY; in cc2_data_fetch()
352 return -EIO; in cc2_data_fetch()
362 return -EINVAL; in cc2_data_fetch()
374 if (data->irq_ready > 0) { in cc2_read_measurement()
376 ret = wait_for_completion_timeout(&data->complete, timeout); in cc2_read_measurement()
378 return -ETIMEDOUT; in cc2_read_measurement()
384 ret = cc2_data_fetch(data->client, type, val); in cc2_read_measurement()
414 * exiting the command mode, there is no need to force two power-up sequences.
453 return cc2->rh_alarm.low_alarm_visible ? 0444 : 0; in cc2_is_visible()
455 return cc2->rh_alarm.high_alarm_visible ? 0444 : 0; in cc2_is_visible()
458 return cc2->rh_alarm.low_alarm_visible ? 0644 : 0; in cc2_is_visible()
461 return cc2->rh_alarm.high_alarm_visible ? 0644 : 0; in cc2_is_visible()
483 if (cc2->process_irqs) in cc2_ready_interrupt()
484 complete(&cc2->complete); in cc2_ready_interrupt()
493 if (cc2->process_irqs) { in cc2_low_interrupt()
494 hwmon_notify_event(cc2->hwmon, hwmon_humidity, in cc2_low_interrupt()
496 cc2->rh_alarm.low_alarm = true; in cc2_low_interrupt()
506 if (cc2->process_irqs) { in cc2_high_interrupt()
507 hwmon_notify_event(cc2->hwmon, hwmon_humidity, in cc2_high_interrupt()
509 cc2->rh_alarm.high_alarm = true; in cc2_high_interrupt()
525 if (data->rh_alarm.low_alarm) { in cc2_humidity_min_alarm_status()
527 data->rh_alarm.low_alarm = *val; in cc2_humidity_min_alarm_status()
545 if (data->rh_alarm.high_alarm) { in cc2_humidity_max_alarm_status()
547 data->rh_alarm.high_alarm = *val; in cc2_humidity_max_alarm_status()
561 mutex_lock(&data->dev_access_lock); in cc2_read()
591 ret = -EOPNOTSUPP; in cc2_read()
595 ret = -EOPNOTSUPP; in cc2_read()
598 mutex_unlock(&data->dev_access_lock); in cc2_read()
612 return -EOPNOTSUPP; in cc2_write()
615 return -EINVAL; in cc2_write()
617 mutex_lock(&data->dev_access_lock); in cc2_write()
645 ret = -EOPNOTSUPP; in cc2_write()
649 mutex_unlock(&data->dev_access_lock); in cc2_write()
658 data->irq_ready = fwnode_irq_get_byname(dev_fwnode(dev), "ready"); in cc2_request_ready_irq()
659 if (data->irq_ready > 0) { in cc2_request_ready_irq()
660 init_completion(&data->complete); in cc2_request_ready_irq()
661 ret = devm_request_threaded_irq(dev, data->irq_ready, NULL, in cc2_request_ready_irq()
675 data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low"); in cc2_request_alarm_irqs()
676 if (data->irq_low > 0) { in cc2_request_alarm_irqs()
677 ret = devm_request_threaded_irq(dev, data->irq_low, NULL, in cc2_request_alarm_irqs()
685 data->rh_alarm.low_alarm_visible = true; in cc2_request_alarm_irqs()
688 data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high"); in cc2_request_alarm_irqs()
689 if (data->irq_high > 0) { in cc2_request_alarm_irqs()
690 ret = devm_request_threaded_irq(dev, data->irq_high, NULL, in cc2_request_alarm_irqs()
698 data->rh_alarm.high_alarm_visible = true; in cc2_request_alarm_irqs()
726 struct device *dev = &client->dev; in cc2_probe()
729 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) in cc2_probe()
730 return -EOPNOTSUPP; in cc2_probe()
734 return -ENOMEM; in cc2_probe()
738 mutex_init(&data->dev_access_lock); in cc2_probe()
740 data->client = client; in cc2_probe()
742 data->regulator = devm_regulator_get_exclusive(dev, "vdd"); in cc2_probe()
743 if (IS_ERR(data->regulator)) in cc2_probe()
744 return dev_err_probe(dev, PTR_ERR(data->regulator), in cc2_probe()
755 data->hwmon = devm_hwmon_device_register_with_info(dev, client->name, in cc2_probe()
758 if (IS_ERR(data->hwmon)) in cc2_probe()
759 return dev_err_probe(dev, PTR_ERR(data->hwmon), in cc2_probe()