drivers/w1/slaves/w1_ds2438.c

Source file repositories/reference/linux-study-clean/drivers/w1/slaves/w1_ds2438.c

File Facts

System
Linux kernel
Corpus path
drivers/w1/slaves/w1_ds2438.c
Extension
.c
Size
12027 bytes
Lines
517
Domain
Driver Families
Bucket
drivers/w1
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

if (count == DS2438_PAGE_SIZE + 1) {
			crc = w1_calc_crc8(buf, DS2438_PAGE_SIZE);

			/* check for correct CRC */
			if ((u8)buf[DS2438_PAGE_SIZE] == crc)
				return 0;
		}
	}
	return -1;
}

static int w1_ds2438_get_temperature(struct w1_slave *sl, int16_t *temperature)
{
	unsigned int retries = W1_DS2438_RETRIES;
	u8 w1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/];
	unsigned int tm = DS2438_MAX_CONVERSION_TIME;
	unsigned long sleep_rem;
	int ret;

	mutex_lock(&sl->master->bus_mutex);

	while (retries--) {
		if (w1_reset_select_slave(sl))
			continue;
		w1_write_8(sl->master, W1_DS2438_CONVERT_TEMP);

		mutex_unlock(&sl->master->bus_mutex);
		sleep_rem = msleep_interruptible(tm);
		if (sleep_rem != 0) {
			ret = -1;
			goto post_unlock;
		}

		if (mutex_lock_interruptible(&sl->master->bus_mutex) != 0) {
			ret = -1;
			goto post_unlock;
		}

		break;
	}

	if (w1_ds2438_get_page(sl, 0, w1_buf) == 0) {
		*temperature = (((int16_t) w1_buf[DS2438_TEMP_MSB]) << 8) | ((uint16_t) w1_buf[DS2438_TEMP_LSB]);
		ret = 0;
	} else
		ret = -1;

	mutex_unlock(&sl->master->bus_mutex);

post_unlock:
	return ret;
}

static int w1_ds2438_change_config_bit(struct w1_slave *sl, u8 mask, u8 value)
{
	unsigned int retries = W1_DS2438_RETRIES;
	u8 w1_buf[3];
	u8 status;
	int perform_write = 0;

	while (retries--) {
		if (w1_reset_select_slave(sl))
			continue;
		w1_buf[0] = W1_DS2438_RECALL_MEMORY;
		w1_buf[1] = 0x00;
		w1_write_block(sl->master, w1_buf, 2);

		if (w1_reset_select_slave(sl))
			continue;
		w1_buf[0] = W1_DS2438_READ_SCRATCH;
		w1_buf[1] = 0x00;
		w1_write_block(sl->master, w1_buf, 2);

		/* reading one byte of result */
		status = w1_read_8(sl->master);

		/* if bit0=1, set a value to a mask for easy compare */
		if (value)
			value = mask;

		if ((status & mask) == value)
			return 0;	/* already set as requested */

		/* changing bit */
		status ^= mask;
		perform_write = 1;

		break;
	}

Annotation

Implementation Notes