1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Hardware monitoring driver for Maxim MAX16064
4 *
5 * Copyright (c) 2011 Ericsson AB.
6 */
7
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/err.h>
12#include <linux/i2c.h>
13#include "pmbus.h"
14
15#define MAX16064_MFR_VOUT_PEAK		0xd4
16#define MAX16064_MFR_TEMPERATURE_PEAK	0xd6
17
18static int max16064_read_word_data(struct i2c_client *client, int page,
19				   int phase, int reg)
20{
21	int ret;
22
23	switch (reg) {
24	case PMBUS_VIRT_READ_VOUT_MAX:
25		ret = pmbus_read_word_data(client, page, phase,
26					   MAX16064_MFR_VOUT_PEAK);
27		break;
28	case PMBUS_VIRT_READ_TEMP_MAX:
29		ret = pmbus_read_word_data(client, page, phase,
30					   MAX16064_MFR_TEMPERATURE_PEAK);
31		break;
32	case PMBUS_VIRT_RESET_VOUT_HISTORY:
33	case PMBUS_VIRT_RESET_TEMP_HISTORY:
34		ret = 0;
35		break;
36	default:
37		ret = -ENODATA;
38		break;
39	}
40	return ret;
41}
42
43static int max16064_write_word_data(struct i2c_client *client, int page,
44				    int reg, u16 word)
45{
46	int ret;
47
48	switch (reg) {
49	case PMBUS_VIRT_RESET_VOUT_HISTORY:
50		ret = pmbus_write_word_data(client, page,
51					    MAX16064_MFR_VOUT_PEAK, 0);
52		break;
53	case PMBUS_VIRT_RESET_TEMP_HISTORY:
54		ret = pmbus_write_word_data(client, page,
55					    MAX16064_MFR_TEMPERATURE_PEAK,
56					    0xffff);
57		break;
58	default:
59		ret = -ENODATA;
60		break;
61	}
62	return ret;
63}
64
65static struct pmbus_driver_info max16064_info = {
66	.pages = 4,
67	.format[PSC_VOLTAGE_IN] = direct,
68	.format[PSC_VOLTAGE_OUT] = direct,
69	.format[PSC_TEMPERATURE] = direct,
70	.m[PSC_VOLTAGE_IN] = 19995,
71	.b[PSC_VOLTAGE_IN] = 0,
72	.R[PSC_VOLTAGE_IN] = -1,
73	.m[PSC_VOLTAGE_OUT] = 19995,
74	.b[PSC_VOLTAGE_OUT] = 0,
75	.R[PSC_VOLTAGE_OUT] = -1,
76	.m[PSC_TEMPERATURE] = -7612,
77	.b[PSC_TEMPERATURE] = 335,
78	.R[PSC_TEMPERATURE] = -3,
79	.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP
80		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP,
81	.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
82	.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
83	.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
84	.read_word_data = max16064_read_word_data,
85	.write_word_data = max16064_write_word_data,
86};
87
88static int max16064_probe(struct i2c_client *client)
89{
90	return pmbus_do_probe(client, &max16064_info);
91}
92
93static const struct i2c_device_id max16064_id[] = {
94	{"max16064", 0},
95	{}
96};
97
98MODULE_DEVICE_TABLE(i2c, max16064_id);
99
100/* This is the driver that will be inserted */
101static struct i2c_driver max16064_driver = {
102	.driver = {
103		   .name = "max16064",
104		   },
105	.probe = max16064_probe,
106	.id_table = max16064_id,
107};
108
109module_i2c_driver(max16064_driver);
110
111MODULE_AUTHOR("Guenter Roeck");
112MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064");
113MODULE_LICENSE("GPL");
114MODULE_IMPORT_NS(PMBUS);
115