blob: 23fba474f16ec67835e1afd1a8de8fa17a1d2608 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Arthur Heymans24231ac2017-06-06 09:46:01 +02003
4#include <assert.h>
5#include <console/console.h>
6#include <device/device.h>
7#include <device/smbus.h>
Arthur Heymans24231ac2017-06-06 09:46:01 +02008#include "chip.h"
Arthur Heymans24231ac2017-06-06 09:46:01 +02009
10#define SMBUS_BLOCK_SIZE 32
11
12static void ck505_init(struct device *dev)
13{
14 struct drivers_i2c_ck505_config *config;
15 int dev_nregs, nregs;
16 u8 block[SMBUS_BLOCK_SIZE];
17 int i;
18
19 if (!dev->enabled || dev->path.type != DEVICE_PATH_I2C)
20 return;
21
22 config = dev->chip_info;
23
24 dev_nregs = smbus_block_read(dev, 0, sizeof(block), block);
25
26 if (dev_nregs < 0) {
27 printk(BIOS_ERR, "Failed reading ck505 configuration!\n");
28 return;
29 }
30
31 /* This means that the devicetree doesn't have to specify nregs */
32 nregs = MIN(MIN(dev_nregs, config->nregs == 0 ? SMBUS_BLOCK_SIZE
33 : config->nregs), ARRAY_SIZE(config->mask));
34
35
36 printk(BIOS_DEBUG, "Changing %d of the %d ck505 config bytes.\n",
37 nregs, dev_nregs);
38
39 assert(ARRAY_SIZE(config->mask) == ARRAY_SIZE(config->regs));
40
41 for (i = 0; i < nregs && i < SMBUS_BLOCK_SIZE; i++)
42 block[i] = (block[i] & ~config->mask[i]) | config->regs[i];
43
44 if (smbus_block_write(dev, 0, dev_nregs, block) < 0)
45 printk(BIOS_ERR, "Failed writing ck505 configuration!\n");
46}
47
48static struct device_operations ck505_operations = {
49 .read_resources = DEVICE_NOOP,
50 .set_resources = DEVICE_NOOP,
51 .enable_resources = DEVICE_NOOP,
52 .init = ck505_init,
53};
54
55static void enable_dev(struct device *dev)
56{
57 dev->ops = &ck505_operations;
58}
59
60struct chip_operations drivers_i2c_ck505_ops = {
61 CHIP_NAME("CK505 Clock generator")
62 .enable_dev = enable_dev,
63};