drivers/iio/adc/hx711.c

Source file repositories/reference/linux-study-clean/drivers/iio/adc/hx711.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/hx711.c
Extension
.c
Size
13287 bytes
Lines
578
Domain
Driver Families
Bucket
drivers/iio
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 hx711_gain_to_scale {
	int			gain;
	int			gain_pulse;
	int			scale;
	int			channel;
};

/*
 * .scale depends on AVDD which in turn is known as soon as the regulator
 * is available
 * therefore we set .scale in hx711_probe()
 *
 * channel A in documentation is channel 0 in source code
 * channel B in documentation is channel 1 in source code
 */
static struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = {
	{ 128, 1, 0, 0 },
	{  32, 2, 0, 1 },
	{  64, 3, 0, 0 }
};

static int hx711_get_gain_to_pulse(int gain)
{
	int i;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		if (hx711_gain_to_scale[i].gain == gain)
			return hx711_gain_to_scale[i].gain_pulse;
	return 1;
}

static int hx711_get_gain_to_scale(int gain)
{
	int i;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		if (hx711_gain_to_scale[i].gain == gain)
			return hx711_gain_to_scale[i].scale;
	return 0;
}

static int hx711_get_scale_to_gain(int scale)
{
	int i;

	for (i = 0; i < HX711_GAIN_MAX; i++)
		if (hx711_gain_to_scale[i].scale == scale)
			return hx711_gain_to_scale[i].gain;
	return -EINVAL;
}

struct hx711_data {
	struct device		*dev;
	struct gpio_desc	*gpiod_pd_sck;
	struct gpio_desc	*gpiod_dout;
	int			gain_set;	/* gain set on device */
	int			gain_chan_a;	/* gain for channel A */
	struct mutex		lock;
	/*
	 * triggered buffer
	 * 2x32-bit channel + 64-bit naturally aligned timestamp
	 */
	struct {
		u32 channel[2];
		aligned_s64 timestamp;
	} buffer;
	/*
	 * delay after a rising edge on SCK until the data is ready DOUT
	 * this is dependent on the hx711 where the datasheet tells a
	 * maximum value of 100 ns
	 * but also on potential parasitic capacities on the wiring
	 */
	u32			data_ready_delay_ns;
	u32			clock_frequency;
};

static int hx711_cycle(struct hx711_data *hx711_data)
{
	unsigned long flags;

	/*
	 * if preempted for more then 60us while PD_SCK is high:
	 * hx711 is going in reset
	 * ==> measuring is false
	 */
	local_irq_save(flags);
	gpiod_set_value(hx711_data->gpiod_pd_sck, 1);

	/*
	 * wait until DOUT is ready

Annotation

Implementation Notes