drivers/misc/ics932s401.c

Source file repositories/reference/linux-study-clean/drivers/misc/ics932s401.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/ics932s401.c
Extension
.c
Size
12802 bytes
Lines
482
Domain
Driver Families
Bucket
drivers/misc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ics932s401_data {
	struct attribute_group	attrs;
	struct mutex		lock;
	char			sensors_valid;
	unsigned long		sensors_last_updated;	/* In jiffies */

	u8			regs[NUM_REGS];
};

static int ics932s401_probe(struct i2c_client *client);
static int ics932s401_detect(struct i2c_client *client,
			  struct i2c_board_info *info);
static void ics932s401_remove(struct i2c_client *client);

static const struct i2c_device_id ics932s401_id[] = {
	{ "ics932s401" },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ics932s401_id);

static struct i2c_driver ics932s401_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name	= "ics932s401",
	},
	.probe		= ics932s401_probe,
	.remove		= ics932s401_remove,
	.id_table	= ics932s401_id,
	.detect		= ics932s401_detect,
	.address_list	= normal_i2c,
};

static struct ics932s401_data *ics932s401_update_device(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ics932s401_data *data = i2c_get_clientdata(client);
	unsigned long local_jiffies = jiffies;
	int i, temp;

	mutex_lock(&data->lock);
	if (time_before(local_jiffies, data->sensors_last_updated +
		SENSOR_REFRESH_INTERVAL)
		&& data->sensors_valid)
		goto out;

	/*
	 * Each register must be read as a word and then right shifted 8 bits.
	 * Not really sure why this is; setting the "byte count programming"
	 * register to 1 does not fix this problem.
	 */
	for (i = 0; i < NUM_MIRRORED_REGS; i++) {
		temp = i2c_smbus_read_word_data(client, regs_to_copy[i]);
		if (temp < 0)
			temp = 0;
		data->regs[regs_to_copy[i]] = temp >> 8;
	}

	data->sensors_last_updated = local_jiffies;
	data->sensors_valid = 1;

out:
	mutex_unlock(&data->lock);
	return data;
}

static ssize_t show_spread_enabled(struct device *dev,
				   struct device_attribute *devattr,
				   char *buf)
{
	struct ics932s401_data *data = ics932s401_update_device(dev);

	if (data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD)
		return sprintf(buf, "1\n");

	return sprintf(buf, "0\n");
}

/* bit to cpu khz map */
static const int fs_speeds[] = {
	266666,
	133333,
	200000,
	166666,
	333333,
	100000,
	400000,
	0,
};

/* clock divisor map */

Annotation

Implementation Notes