Message ID | feeabbfd3d3916c7497dfd94423ff83ef5f654f1.1743573284.git.mazziesaccount@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Support ROHM BD79104 ADC | expand |
On 4/2/25 1:09 AM, Matti Vaittinen wrote: > The register data is 12-bit big-endian data. Use be16_to_cpu() to do > the conversion, and simple bitwise AND for masking to make it more > obvious. > > Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com> > --- > Revision history: > v1 => v2: > - Fix commit msg to reflect the fact there was no bug > - Drop Fixes tag > - Use union for rx / tx buffer to avoid casting > - Keep the shared message protected by the mutex > --- > drivers/iio/adc/ti-adc128s052.c | 18 ++++++++++-------- > 1 file changed, 10 insertions(+), 8 deletions(-) > > diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c > index a456ea78462f..3e69a5fce010 100644 > --- a/drivers/iio/adc/ti-adc128s052.c > +++ b/drivers/iio/adc/ti-adc128s052.c > @@ -28,32 +28,34 @@ struct adc128 { > struct regulator *reg; > struct mutex lock; > > - u8 buffer[2] __aligned(IIO_DMA_MINALIGN); > + union { > + __be16 rx_buffer; > + u8 tx_buffer[2]; > + } __aligned(IIO_DMA_MINALIGN); > }; > > static int adc128_adc_conversion(struct adc128 *adc, u8 channel) > { > int ret; > + char *msg = &adc->tx_buffer[0]; > > mutex_lock(&adc->lock); > > - adc->buffer[0] = channel << 3; > - adc->buffer[1] = 0; > + msg[0] = channel << 3; > + msg[1] = 0; > > - ret = spi_write(adc->spi, &adc->buffer, 2); > + ret = spi_write(adc->spi, msg, sizeof(adc->tx_buffer)); > if (ret < 0) { > mutex_unlock(&adc->lock); > return ret; > } > > - ret = spi_read(adc->spi, &adc->buffer, 2); > - > + ret = spi_read(adc->spi, &adc->rx_buffer, 2); > mutex_unlock(&adc->lock); > - > if (ret < 0) > return ret; > > - return ((adc->buffer[0] << 8 | adc->buffer[1]) & 0xFFF); > + return be16_to_cpu(adc->rx_buffer) & 0xFFF; The cast isn't exactly beautiful, but this would save a lot of lines of diff and a few lines of code by avoiding the need for the union and the local msg variable. return be16_to_cpup((__be16 *)adc->buffer) & 0xFFF; > } > > static int adc128_read_raw(struct iio_dev *indio_dev,
On 03/04/2025 00:04, David Lechner wrote: > On 4/2/25 1:09 AM, Matti Vaittinen wrote: >> The register data is 12-bit big-endian data. Use be16_to_cpu() to do >> the conversion, and simple bitwise AND for masking to make it more >> obvious. >> >> Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com> >> --- >> Revision history: >> v1 => v2: >> - Fix commit msg to reflect the fact there was no bug >> - Drop Fixes tag >> - Use union for rx / tx buffer to avoid casting >> - Keep the shared message protected by the mutex >> --- >> drivers/iio/adc/ti-adc128s052.c | 18 ++++++++++-------- >> 1 file changed, 10 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c >> index a456ea78462f..3e69a5fce010 100644 >> --- a/drivers/iio/adc/ti-adc128s052.c >> +++ b/drivers/iio/adc/ti-adc128s052.c >> @@ -28,32 +28,34 @@ struct adc128 { >> struct regulator *reg; >> struct mutex lock; >> >> - u8 buffer[2] __aligned(IIO_DMA_MINALIGN); >> + union { >> + __be16 rx_buffer; >> + u8 tx_buffer[2]; >> + } __aligned(IIO_DMA_MINALIGN); >> }; >> >> static int adc128_adc_conversion(struct adc128 *adc, u8 channel) >> { >> int ret; >> + char *msg = &adc->tx_buffer[0]; >> >> mutex_lock(&adc->lock); >> >> - adc->buffer[0] = channel << 3; >> - adc->buffer[1] = 0; >> + msg[0] = channel << 3; >> + msg[1] = 0; >> >> - ret = spi_write(adc->spi, &adc->buffer, 2); >> + ret = spi_write(adc->spi, msg, sizeof(adc->tx_buffer)); >> if (ret < 0) { >> mutex_unlock(&adc->lock); >> return ret; >> } >> >> - ret = spi_read(adc->spi, &adc->buffer, 2); >> - >> + ret = spi_read(adc->spi, &adc->rx_buffer, 2); >> mutex_unlock(&adc->lock); >> - >> if (ret < 0) >> return ret; >> >> - return ((adc->buffer[0] << 8 | adc->buffer[1]) & 0xFFF); >> + return be16_to_cpu(adc->rx_buffer) & 0xFFF; > > > The cast isn't exactly beautiful, but this would save a lot of > lines of diff and a few lines of code by avoiding the need for > the union and the local msg variable. > > return be16_to_cpup((__be16 *)adc->buffer) & 0xFFF; Thanks again for the review David :) I am unsure which way to go. I kind of like having the __be16 in the struct, as it immediately yells "data from device is big-endian". OTOH, I've never loved unions (and, it silences the above "yelling" quite a bit). I still think this might be the first time I really see a valid use-case for an union :) And, you're right this adds more lines, besides, the cast doesn't look that ugly to me. Yet, I originally had a cast probably as simple as this (and I also had the __be16 in the struct), and Jonathan suggested using union to avoid it... At the end of the day, I suppose I am Okay with any of these 3 approaches. Original cast, union or this cast you suggest. Jonathan, any preferences on your side? > >> } >> >> static int adc128_read_raw(struct iio_dev *indio_dev, > Yours, -- Matti
diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index a456ea78462f..3e69a5fce010 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c @@ -28,32 +28,34 @@ struct adc128 { struct regulator *reg; struct mutex lock; - u8 buffer[2] __aligned(IIO_DMA_MINALIGN); + union { + __be16 rx_buffer; + u8 tx_buffer[2]; + } __aligned(IIO_DMA_MINALIGN); }; static int adc128_adc_conversion(struct adc128 *adc, u8 channel) { int ret; + char *msg = &adc->tx_buffer[0]; mutex_lock(&adc->lock); - adc->buffer[0] = channel << 3; - adc->buffer[1] = 0; + msg[0] = channel << 3; + msg[1] = 0; - ret = spi_write(adc->spi, &adc->buffer, 2); + ret = spi_write(adc->spi, msg, sizeof(adc->tx_buffer)); if (ret < 0) { mutex_unlock(&adc->lock); return ret; } - ret = spi_read(adc->spi, &adc->buffer, 2); - + ret = spi_read(adc->spi, &adc->rx_buffer, 2); mutex_unlock(&adc->lock); - if (ret < 0) return ret; - return ((adc->buffer[0] << 8 | adc->buffer[1]) & 0xFFF); + return be16_to_cpu(adc->rx_buffer) & 0xFFF; } static int adc128_read_raw(struct iio_dev *indio_dev,
The register data is 12-bit big-endian data. Use be16_to_cpu() to do the conversion, and simple bitwise AND for masking to make it more obvious. Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com> --- Revision history: v1 => v2: - Fix commit msg to reflect the fact there was no bug - Drop Fixes tag - Use union for rx / tx buffer to avoid casting - Keep the shared message protected by the mutex --- drivers/iio/adc/ti-adc128s052.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)