1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2017 IBM Corp.
6 #include <linux/bitfield.h>
7 #include <linux/bitops.h>
8 #include <linux/debugfs.h>
9 #include <linux/device.h>
11 #include <linux/i2c.h>
12 #include <linux/jiffies.h>
13 #include <linux/leds.h>
14 #include <linux/module.h>
15 #include <linux/mutex.h>
17 #include <linux/pmbus.h>
21 #define CFFPS_CCIN_CMD 0xBD
22 #define CFFPS_FW_CMD 0xFA
23 #define CFFPS1_FW_NUM_BYTES 4
24 #define CFFPS2_FW_NUM_WORDS 3
25 #define CFFPS_SYS_CONFIG_CMD 0xDA
26 #define CFFPS_12VCS_VOUT_CMD 0xDE
28 #define CFFPS_INPUT_HISTORY_CMD 0xD6
29 #define CFFPS_INPUT_HISTORY_SIZE 101
31 #define CFFPS_CCIN_REVISION GENMASK(7, 0)
32 #define CFFPS_CCIN_REVISION_LEGACY 0xde
33 #define CFFPS_CCIN_VERSION GENMASK(15, 8)
34 #define CFFPS_CCIN_VERSION_1 0x2b
35 #define CFFPS_CCIN_VERSION_2 0x2e
36 #define CFFPS_CCIN_VERSION_3 0x51
38 /* STATUS_MFR_SPECIFIC bits */
39 #define CFFPS_MFR_FAN_FAULT BIT(0)
40 #define CFFPS_MFR_THERMAL_FAULT BIT(1)
41 #define CFFPS_MFR_OV_FAULT BIT(2)
42 #define CFFPS_MFR_UV_FAULT BIT(3)
43 #define CFFPS_MFR_PS_KILL BIT(4)
44 #define CFFPS_MFR_OC_FAULT BIT(5)
45 #define CFFPS_MFR_VAUX_FAULT BIT(6)
46 #define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7)
48 #define CFFPS_LED_BLINK (BIT(0) | BIT(6))
49 #define CFFPS_LED_ON (BIT(1) | BIT(6))
50 #define CFFPS_LED_OFF (BIT(2) | BIT(6))
51 #define CFFPS_BLINK_RATE_MS 250
54 CFFPS_DEBUGFS_MAX_POWER_OUT
= 0,
57 CFFPS_DEBUGFS_ON_OFF_CONFIG
,
58 CFFPS_DEBUGFS_NUM_ENTRIES
61 enum versions
{ cffps1
, cffps2
, cffps_unknown
};
64 enum versions version
;
65 struct i2c_client
*client
;
67 u8 input_history
[CFFPS_INPUT_HISTORY_SIZE
];
69 int debugfs_entries
[CFFPS_DEBUGFS_NUM_ENTRIES
];
73 struct led_classdev led
;
76 #define to_psu(x, y) container_of((x), struct ibm_cffps, debugfs_entries[(y)])
78 static ssize_t
ibm_cffps_debugfs_read_input_history(struct file
*file
, char __user
*buf
,
79 size_t count
, loff_t
*ppos
)
82 u8 cmd
= CFFPS_INPUT_HISTORY_CMD
;
83 struct ibm_cffps
*psu
= file
->private_data
;
84 struct i2c_msg msg
[2] = {
86 .addr
= psu
->client
->addr
,
87 .flags
= psu
->client
->flags
,
91 .addr
= psu
->client
->addr
,
92 .flags
= psu
->client
->flags
| I2C_M_RD
,
93 .len
= CFFPS_INPUT_HISTORY_SIZE
,
94 .buf
= psu
->input_history
,
99 rc
= pmbus_lock_interruptible(psu
->client
);
103 rc
= pmbus_set_page(psu
->client
, 0, 0xff);
105 pmbus_unlock(psu
->client
);
110 * Use a raw i2c transfer, since we need more bytes
111 * than Linux I2C supports through smbus xfr (only 32).
113 rc
= i2c_transfer(psu
->client
->adapter
, msg
, 2);
114 pmbus_unlock(psu
->client
);
119 return simple_read_from_buffer(buf
, count
, ppos
,
120 psu
->input_history
+ 1,
121 psu
->input_history
[0]);
124 static const struct file_operations ibm_cffps_input_history_fops
= {
125 .llseek
= noop_llseek
,
126 .read
= ibm_cffps_debugfs_read_input_history
,
130 static ssize_t
ibm_cffps_debugfs_read(struct file
*file
, char __user
*buf
,
131 size_t count
, loff_t
*ppos
)
134 int *idxp
= file
->private_data
;
136 struct ibm_cffps
*psu
= to_psu(idxp
, idx
);
137 char data
[I2C_SMBUS_BLOCK_MAX
+ 2] = { 0 };
139 rc
= pmbus_lock_interruptible(psu
->client
);
143 rc
= pmbus_set_page(psu
->client
, 0, 0xff);
148 case CFFPS_DEBUGFS_MAX_POWER_OUT
:
149 if (psu
->version
== cffps1
)
150 rc
= i2c_smbus_read_word_swapped(psu
->client
, PMBUS_MFR_POUT_MAX
);
152 rc
= i2c_smbus_read_word_data(psu
->client
, PMBUS_MFR_POUT_MAX
);
154 rc
= snprintf(data
, I2C_SMBUS_BLOCK_MAX
, "%d", rc
);
156 case CFFPS_DEBUGFS_CCIN
:
157 rc
= i2c_smbus_read_word_swapped(psu
->client
, CFFPS_CCIN_CMD
);
159 rc
= snprintf(data
, 5, "%04X", rc
);
161 case CFFPS_DEBUGFS_FW
:
162 switch (psu
->version
) {
164 for (i
= 0; i
< CFFPS1_FW_NUM_BYTES
; ++i
) {
165 rc
= i2c_smbus_read_byte_data(psu
->client
, CFFPS_FW_CMD
+ i
);
169 snprintf(&data
[i
* 2], 3, "%02X", rc
);
175 for (i
= 0; i
< CFFPS2_FW_NUM_WORDS
; ++i
) {
176 rc
= i2c_smbus_read_word_data(psu
->client
, CFFPS_FW_CMD
+ i
);
180 snprintf(&data
[i
* 4], 5, "%04X", rc
);
190 case CFFPS_DEBUGFS_ON_OFF_CONFIG
:
191 rc
= i2c_smbus_read_byte_data(psu
->client
, PMBUS_ON_OFF_CONFIG
);
193 rc
= snprintf(data
, 3, "%02x", rc
);
201 pmbus_unlock(psu
->client
);
208 return simple_read_from_buffer(buf
, count
, ppos
, data
, rc
);
211 static ssize_t
ibm_cffps_debugfs_write(struct file
*file
,
212 const char __user
*buf
, size_t count
,
217 int *idxp
= file
->private_data
;
219 struct ibm_cffps
*psu
= to_psu(idxp
, idx
);
222 case CFFPS_DEBUGFS_ON_OFF_CONFIG
:
223 rc
= simple_write_to_buffer(&data
, 1, ppos
, buf
, count
);
227 rc
= pmbus_lock_interruptible(psu
->client
);
231 rc
= pmbus_set_page(psu
->client
, 0, 0xff);
233 pmbus_unlock(psu
->client
);
237 rc
= i2c_smbus_write_byte_data(psu
->client
, PMBUS_ON_OFF_CONFIG
, data
);
238 pmbus_unlock(psu
->client
);
251 static const struct file_operations ibm_cffps_fops
= {
252 .llseek
= noop_llseek
,
253 .read
= ibm_cffps_debugfs_read
,
254 .write
= ibm_cffps_debugfs_write
,
258 static int ibm_cffps_read_byte_data(struct i2c_client
*client
, int page
,
264 case PMBUS_STATUS_VOUT
:
265 case PMBUS_STATUS_IOUT
:
266 case PMBUS_STATUS_TEMPERATURE
:
267 case PMBUS_STATUS_FAN_12
:
268 rc
= pmbus_read_byte_data(client
, page
, reg
);
272 mfr
= pmbus_read_byte_data(client
, page
,
273 PMBUS_STATUS_MFR_SPECIFIC
);
276 * Return the status register instead of an error,
277 * since we successfully read status.
281 /* Add MFR_SPECIFIC bits to the standard pmbus status regs. */
282 if (reg
== PMBUS_STATUS_FAN_12
) {
283 if (mfr
& CFFPS_MFR_FAN_FAULT
)
284 rc
|= PB_FAN_FAN1_FAULT
;
285 } else if (reg
== PMBUS_STATUS_TEMPERATURE
) {
286 if (mfr
& CFFPS_MFR_THERMAL_FAULT
)
287 rc
|= PB_TEMP_OT_FAULT
;
288 } else if (reg
== PMBUS_STATUS_VOUT
) {
289 if (mfr
& (CFFPS_MFR_OV_FAULT
| CFFPS_MFR_VAUX_FAULT
))
290 rc
|= PB_VOLTAGE_OV_FAULT
;
291 if (mfr
& CFFPS_MFR_UV_FAULT
)
292 rc
|= PB_VOLTAGE_UV_FAULT
;
293 } else if (reg
== PMBUS_STATUS_IOUT
) {
294 if (mfr
& CFFPS_MFR_OC_FAULT
)
295 rc
|= PB_IOUT_OC_FAULT
;
296 if (mfr
& CFFPS_MFR_CURRENT_SHARE_WARNING
)
297 rc
|= PB_CURRENT_SHARE_FAULT
;
308 static int ibm_cffps_read_word_data(struct i2c_client
*client
, int page
,
314 case PMBUS_STATUS_WORD
:
315 rc
= pmbus_read_word_data(client
, page
, phase
, reg
);
319 mfr
= pmbus_read_byte_data(client
, page
,
320 PMBUS_STATUS_MFR_SPECIFIC
);
323 * Return the status register instead of an error,
324 * since we successfully read status.
328 if (mfr
& CFFPS_MFR_PS_KILL
)
331 case PMBUS_VIRT_READ_VMON
:
332 rc
= pmbus_read_word_data(client
, page
, phase
,
333 CFFPS_12VCS_VOUT_CMD
);
343 static int ibm_cffps_led_brightness_set(struct led_classdev
*led_cdev
,
344 enum led_brightness brightness
)
348 struct ibm_cffps
*psu
= container_of(led_cdev
, struct ibm_cffps
, led
);
350 if (brightness
== LED_OFF
) {
351 next_led_state
= CFFPS_LED_OFF
;
353 brightness
= LED_FULL
;
355 if (psu
->led_state
!= CFFPS_LED_BLINK
)
356 next_led_state
= CFFPS_LED_ON
;
358 next_led_state
= CFFPS_LED_BLINK
;
361 dev_dbg(&psu
->client
->dev
, "LED brightness set: %d. Command: %d.\n",
362 brightness
, next_led_state
);
364 rc
= pmbus_lock_interruptible(psu
->client
);
368 rc
= pmbus_set_page(psu
->client
, 0, 0xff);
370 pmbus_unlock(psu
->client
);
374 rc
= i2c_smbus_write_byte_data(psu
->client
, CFFPS_SYS_CONFIG_CMD
,
376 pmbus_unlock(psu
->client
);
380 psu
->led_state
= next_led_state
;
381 led_cdev
->brightness
= brightness
;
386 static int ibm_cffps_led_blink_set(struct led_classdev
*led_cdev
,
387 unsigned long *delay_on
,
388 unsigned long *delay_off
)
391 struct ibm_cffps
*psu
= container_of(led_cdev
, struct ibm_cffps
, led
);
393 dev_dbg(&psu
->client
->dev
, "LED blink set.\n");
395 rc
= pmbus_lock_interruptible(psu
->client
);
399 rc
= pmbus_set_page(psu
->client
, 0, 0xff);
401 pmbus_unlock(psu
->client
);
405 rc
= i2c_smbus_write_byte_data(psu
->client
, CFFPS_SYS_CONFIG_CMD
,
407 pmbus_unlock(psu
->client
);
411 psu
->led_state
= CFFPS_LED_BLINK
;
412 led_cdev
->brightness
= LED_FULL
;
413 *delay_on
= CFFPS_BLINK_RATE_MS
;
414 *delay_off
= CFFPS_BLINK_RATE_MS
;
419 static void ibm_cffps_create_led_class(struct ibm_cffps
*psu
)
422 struct i2c_client
*client
= psu
->client
;
423 struct device
*dev
= &client
->dev
;
425 snprintf(psu
->led_name
, sizeof(psu
->led_name
), "%s-%02x", client
->name
,
427 psu
->led
.name
= psu
->led_name
;
428 psu
->led
.max_brightness
= LED_FULL
;
429 psu
->led
.brightness_set_blocking
= ibm_cffps_led_brightness_set
;
430 psu
->led
.blink_set
= ibm_cffps_led_blink_set
;
432 rc
= devm_led_classdev_register(dev
, &psu
->led
);
434 dev_warn(dev
, "failed to register led class: %d\n", rc
);
436 i2c_smbus_write_byte_data(client
, CFFPS_SYS_CONFIG_CMD
,
440 static struct pmbus_driver_info ibm_cffps_info
[] = {
443 .func
[0] = PMBUS_HAVE_VIN
| PMBUS_HAVE_VOUT
| PMBUS_HAVE_IOUT
|
444 PMBUS_HAVE_PIN
| PMBUS_HAVE_FAN12
| PMBUS_HAVE_TEMP
|
445 PMBUS_HAVE_TEMP2
| PMBUS_HAVE_TEMP3
|
446 PMBUS_HAVE_STATUS_VOUT
| PMBUS_HAVE_STATUS_IOUT
|
447 PMBUS_HAVE_STATUS_INPUT
| PMBUS_HAVE_STATUS_TEMP
|
448 PMBUS_HAVE_STATUS_FAN12
,
449 .read_byte_data
= ibm_cffps_read_byte_data
,
450 .read_word_data
= ibm_cffps_read_word_data
,
454 .func
[0] = PMBUS_HAVE_VIN
| PMBUS_HAVE_VOUT
| PMBUS_HAVE_IOUT
|
455 PMBUS_HAVE_PIN
| PMBUS_HAVE_FAN12
| PMBUS_HAVE_TEMP
|
456 PMBUS_HAVE_TEMP2
| PMBUS_HAVE_TEMP3
|
457 PMBUS_HAVE_STATUS_VOUT
| PMBUS_HAVE_STATUS_IOUT
|
458 PMBUS_HAVE_STATUS_INPUT
| PMBUS_HAVE_STATUS_TEMP
|
459 PMBUS_HAVE_STATUS_FAN12
| PMBUS_HAVE_VMON
,
460 .func
[1] = PMBUS_HAVE_VIN
| PMBUS_HAVE_VOUT
| PMBUS_HAVE_IOUT
|
461 PMBUS_HAVE_PIN
| PMBUS_HAVE_TEMP
| PMBUS_HAVE_TEMP2
|
462 PMBUS_HAVE_TEMP3
| PMBUS_HAVE_STATUS_VOUT
|
463 PMBUS_HAVE_STATUS_IOUT
| PMBUS_HAVE_STATUS_INPUT
|
464 PMBUS_HAVE_STATUS_TEMP
,
465 .read_byte_data
= ibm_cffps_read_byte_data
,
466 .read_word_data
= ibm_cffps_read_word_data
,
470 static struct pmbus_platform_data ibm_cffps_pdata
= {
471 .flags
= PMBUS_SKIP_STATUS_CHECK
| PMBUS_NO_CAPABILITY
,
474 static const struct i2c_device_id ibm_cffps_id
[] = {
475 { "ibm_cffps1", cffps1
},
476 { "ibm_cffps2", cffps2
},
477 { "ibm_cffps", cffps_unknown
},
480 MODULE_DEVICE_TABLE(i2c
, ibm_cffps_id
);
482 static int ibm_cffps_probe(struct i2c_client
*client
)
485 enum versions vs
= cffps_unknown
;
486 struct dentry
*debugfs
;
487 struct ibm_cffps
*psu
;
488 const void *md
= of_device_get_match_data(&client
->dev
);
489 const struct i2c_device_id
*id
;
494 id
= i2c_match_id(ibm_cffps_id
, client
);
496 vs
= (enum versions
)id
->driver_data
;
499 if (vs
== cffps_unknown
) {
500 u16 ccin_revision
= 0;
501 u16 ccin_version
= CFFPS_CCIN_VERSION_1
;
502 int ccin
= i2c_smbus_read_word_swapped(client
, CFFPS_CCIN_CMD
);
503 char mfg_id
[I2C_SMBUS_BLOCK_MAX
+ 2] = { 0 };
506 ccin_revision
= FIELD_GET(CFFPS_CCIN_REVISION
, ccin
);
507 ccin_version
= FIELD_GET(CFFPS_CCIN_VERSION
, ccin
);
510 rc
= i2c_smbus_read_block_data(client
, PMBUS_MFR_ID
, mfg_id
);
512 dev_err(&client
->dev
, "Failed to read Manufacturer ID\n");
516 switch (ccin_version
) {
518 case CFFPS_CCIN_VERSION_1
:
519 if ((strncmp(mfg_id
, "ACBE", 4) == 0) ||
520 (strncmp(mfg_id
, "ARTE", 4) == 0))
525 case CFFPS_CCIN_VERSION_2
:
528 case CFFPS_CCIN_VERSION_3
:
529 if (ccin_revision
== CFFPS_CCIN_REVISION_LEGACY
)
536 /* Set the client name to include the version number. */
537 snprintf(client
->name
, I2C_NAME_SIZE
, "cffps%d", vs
+ 1);
540 client
->dev
.platform_data
= &ibm_cffps_pdata
;
541 rc
= pmbus_do_probe(client
, &ibm_cffps_info
[vs
]);
546 * Don't fail the probe if there isn't enough memory for leds and
549 psu
= devm_kzalloc(&client
->dev
, sizeof(*psu
), GFP_KERNEL
);
554 psu
->client
= client
;
556 ibm_cffps_create_led_class(psu
);
558 /* Don't fail the probe if we can't create debugfs */
559 debugfs
= pmbus_get_debugfs_dir(client
);
563 for (i
= 0; i
< CFFPS_DEBUGFS_NUM_ENTRIES
; ++i
)
564 psu
->debugfs_entries
[i
] = i
;
566 debugfs_create_file("input_history", 0444, debugfs
, psu
, &ibm_cffps_input_history_fops
);
567 debugfs_create_file("max_power_out", 0444, debugfs
,
568 &psu
->debugfs_entries
[CFFPS_DEBUGFS_MAX_POWER_OUT
],
570 debugfs_create_file("ccin", 0444, debugfs
,
571 &psu
->debugfs_entries
[CFFPS_DEBUGFS_CCIN
],
573 debugfs_create_file("fw_version", 0444, debugfs
,
574 &psu
->debugfs_entries
[CFFPS_DEBUGFS_FW
],
576 debugfs_create_file("on_off_config", 0644, debugfs
,
577 &psu
->debugfs_entries
[CFFPS_DEBUGFS_ON_OFF_CONFIG
],
580 /* For compatibility with users of the old naming scheme. */
581 debugfs_create_symlink(client
->name
, debugfs
, ".");
586 static const struct of_device_id ibm_cffps_of_match
[] = {
588 .compatible
= "ibm,cffps1",
589 .data
= (void *)cffps1
592 .compatible
= "ibm,cffps2",
593 .data
= (void *)cffps2
596 .compatible
= "ibm,cffps",
597 .data
= (void *)cffps_unknown
601 MODULE_DEVICE_TABLE(of
, ibm_cffps_of_match
);
603 static struct i2c_driver ibm_cffps_driver
= {
606 .of_match_table
= ibm_cffps_of_match
,
608 .probe
= ibm_cffps_probe
,
609 .id_table
= ibm_cffps_id
,
612 module_i2c_driver(ibm_cffps_driver
);
614 MODULE_AUTHOR("Eddie James");
615 MODULE_DESCRIPTION("PMBus driver for IBM Common Form Factor power supplies");
616 MODULE_LICENSE("GPL");
617 MODULE_IMPORT_NS(PMBUS
);