162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci /* 362306a36Sopenharmony_ci * iio/adc/max1363.c 462306a36Sopenharmony_ci * Copyright (C) 2008-2010 Jonathan Cameron 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * based on linux/drivers/i2c/chips/max123x 762306a36Sopenharmony_ci * Copyright (C) 2002-2004 Stefan Eletzhofer 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * based on linux/drivers/acron/char/pcf8583.c 1062306a36Sopenharmony_ci * Copyright (C) 2000 Russell King 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Driver for max1363 and similar chips. 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/interrupt.h> 1662306a36Sopenharmony_ci#include <linux/device.h> 1762306a36Sopenharmony_ci#include <linux/kernel.h> 1862306a36Sopenharmony_ci#include <linux/sysfs.h> 1962306a36Sopenharmony_ci#include <linux/list.h> 2062306a36Sopenharmony_ci#include <linux/i2c.h> 2162306a36Sopenharmony_ci#include <linux/regulator/consumer.h> 2262306a36Sopenharmony_ci#include <linux/slab.h> 2362306a36Sopenharmony_ci#include <linux/err.h> 2462306a36Sopenharmony_ci#include <linux/module.h> 2562306a36Sopenharmony_ci#include <linux/mod_devicetable.h> 2662306a36Sopenharmony_ci#include <linux/property.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <linux/iio/iio.h> 2962306a36Sopenharmony_ci#include <linux/iio/sysfs.h> 3062306a36Sopenharmony_ci#include <linux/iio/events.h> 3162306a36Sopenharmony_ci#include <linux/iio/buffer.h> 3262306a36Sopenharmony_ci#include <linux/iio/kfifo_buf.h> 3362306a36Sopenharmony_ci#include <linux/iio/trigger_consumer.h> 3462306a36Sopenharmony_ci#include <linux/iio/triggered_buffer.h> 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define MAX1363_SETUP_BYTE(a) ((a) | 0x80) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* There is a fair bit more defined here than currently 3962306a36Sopenharmony_ci * used, but the intention is to support everything these 4062306a36Sopenharmony_ci * chips do in the long run */ 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* see data sheets */ 4362306a36Sopenharmony_ci/* max1363 and max1236, max1237, max1238, max1239 */ 4462306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00 4562306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20 4662306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40 4762306a36Sopenharmony_ci#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60 4862306a36Sopenharmony_ci#define MAX1363_SETUP_POWER_UP_INT_REF 0x10 4962306a36Sopenharmony_ci#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/* think about including max11600 etc - more settings */ 5262306a36Sopenharmony_ci#define MAX1363_SETUP_EXT_CLOCK 0x08 5362306a36Sopenharmony_ci#define MAX1363_SETUP_INT_CLOCK 0x00 5462306a36Sopenharmony_ci#define MAX1363_SETUP_UNIPOLAR 0x00 5562306a36Sopenharmony_ci#define MAX1363_SETUP_BIPOLAR 0x04 5662306a36Sopenharmony_ci#define MAX1363_SETUP_RESET 0x00 5762306a36Sopenharmony_ci#define MAX1363_SETUP_NORESET 0x02 5862306a36Sopenharmony_ci/* max1363 only - though don't care on others. 5962306a36Sopenharmony_ci * For now monitor modes are not implemented as the relevant 6062306a36Sopenharmony_ci * line is not connected on my test board. 6162306a36Sopenharmony_ci * The definitions are here as I intend to add this soon. 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_ci#define MAX1363_SETUP_MONITOR_SETUP 0x01 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* Specific to the max1363 */ 6662306a36Sopenharmony_ci#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4)) 6762306a36Sopenharmony_ci#define MAX1363_MON_INT_ENABLE 0x01 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* defined for readability reasons */ 7062306a36Sopenharmony_ci/* All chips */ 7162306a36Sopenharmony_ci#define MAX1363_CONFIG_BYTE(a) ((a)) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define MAX1363_CONFIG_SE 0x01 7462306a36Sopenharmony_ci#define MAX1363_CONFIG_DE 0x00 7562306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_TO_CS 0x00 7662306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20 7762306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40 7862306a36Sopenharmony_ci#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60 7962306a36Sopenharmony_ci/* max123{6-9} only */ 8062306a36Sopenharmony_ci#define MAX1236_SCAN_MID_TO_CHANNEL 0x40 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* max1363 only - merely part of channel selects or don't care for others */ 8362306a36Sopenharmony_ci#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define MAX1363_CHANNEL_SEL(a) ((a) << 1) 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* max1363 strictly 0x06 - but doesn't matter */ 8862306a36Sopenharmony_ci#define MAX1363_CHANNEL_SEL_MASK 0x1E 8962306a36Sopenharmony_ci#define MAX1363_SCAN_MASK 0x60 9062306a36Sopenharmony_ci#define MAX1363_SE_DE_MASK 0x01 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#define MAX1363_MAX_CHANNELS 25 9362306a36Sopenharmony_ci/** 9462306a36Sopenharmony_ci * struct max1363_mode - scan mode information 9562306a36Sopenharmony_ci * @conf: The corresponding value of the configuration register 9662306a36Sopenharmony_ci * @modemask: Bit mask corresponding to channels enabled in this mode 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_cistruct max1363_mode { 9962306a36Sopenharmony_ci int8_t conf; 10062306a36Sopenharmony_ci DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS); 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci/* This must be maintained along side the max1363_mode_table in max1363_core */ 10462306a36Sopenharmony_cienum max1363_modes { 10562306a36Sopenharmony_ci /* Single read of a single channel */ 10662306a36Sopenharmony_ci _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, 10762306a36Sopenharmony_ci /* Differential single read */ 10862306a36Sopenharmony_ci d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, 10962306a36Sopenharmony_ci d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, 11062306a36Sopenharmony_ci /* Scan to channel and mid to channel where overlapping */ 11162306a36Sopenharmony_ci s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6, 11262306a36Sopenharmony_ci s6to7, s0to7, s6to8, s0to8, s6to9, 11362306a36Sopenharmony_ci s0to9, s6to10, s0to10, s6to11, s0to11, 11462306a36Sopenharmony_ci /* Differential scan to channel and mid to channel where overlapping */ 11562306a36Sopenharmony_ci d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, 11662306a36Sopenharmony_ci d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, 11762306a36Sopenharmony_ci d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, 11862306a36Sopenharmony_ci d7m6to11m10, d1m0to11m10, 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/** 12262306a36Sopenharmony_ci * struct max1363_chip_info - chip specifc information 12362306a36Sopenharmony_ci * @info: iio core function callbacks structure 12462306a36Sopenharmony_ci * @channels: channel specification 12562306a36Sopenharmony_ci * @num_channels: number of channels 12662306a36Sopenharmony_ci * @mode_list: array of available scan modes 12762306a36Sopenharmony_ci * @default_mode: the scan mode in which the chip starts up 12862306a36Sopenharmony_ci * @int_vref_mv: the internal reference voltage 12962306a36Sopenharmony_ci * @num_modes: number of modes 13062306a36Sopenharmony_ci * @bits: accuracy of the adc in bits 13162306a36Sopenharmony_ci */ 13262306a36Sopenharmony_cistruct max1363_chip_info { 13362306a36Sopenharmony_ci const struct iio_info *info; 13462306a36Sopenharmony_ci const struct iio_chan_spec *channels; 13562306a36Sopenharmony_ci int num_channels; 13662306a36Sopenharmony_ci const enum max1363_modes *mode_list; 13762306a36Sopenharmony_ci enum max1363_modes default_mode; 13862306a36Sopenharmony_ci u16 int_vref_mv; 13962306a36Sopenharmony_ci u8 num_modes; 14062306a36Sopenharmony_ci u8 bits; 14162306a36Sopenharmony_ci}; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/** 14462306a36Sopenharmony_ci * struct max1363_state - driver instance specific data 14562306a36Sopenharmony_ci * @client: i2c_client 14662306a36Sopenharmony_ci * @setupbyte: cache of current device setup byte 14762306a36Sopenharmony_ci * @configbyte: cache of current device config byte 14862306a36Sopenharmony_ci * @chip_info: chip model specific constants, available modes, etc. 14962306a36Sopenharmony_ci * @current_mode: the scan mode of this chip 15062306a36Sopenharmony_ci * @requestedmask: a valid requested set of channels 15162306a36Sopenharmony_ci * @lock: lock to ensure state is consistent 15262306a36Sopenharmony_ci * @monitor_on: whether monitor mode is enabled 15362306a36Sopenharmony_ci * @monitor_speed: parameter corresponding to device monitor speed setting 15462306a36Sopenharmony_ci * @mask_high: bitmask for enabled high thresholds 15562306a36Sopenharmony_ci * @mask_low: bitmask for enabled low thresholds 15662306a36Sopenharmony_ci * @thresh_high: high threshold values 15762306a36Sopenharmony_ci * @thresh_low: low threshold values 15862306a36Sopenharmony_ci * @vref: Reference voltage regulator 15962306a36Sopenharmony_ci * @vref_uv: Actual (external or internal) reference voltage 16062306a36Sopenharmony_ci * @send: function used to send data to the chip 16162306a36Sopenharmony_ci * @recv: function used to receive data from the chip 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_cistruct max1363_state { 16462306a36Sopenharmony_ci struct i2c_client *client; 16562306a36Sopenharmony_ci u8 setupbyte; 16662306a36Sopenharmony_ci u8 configbyte; 16762306a36Sopenharmony_ci const struct max1363_chip_info *chip_info; 16862306a36Sopenharmony_ci const struct max1363_mode *current_mode; 16962306a36Sopenharmony_ci u32 requestedmask; 17062306a36Sopenharmony_ci struct mutex lock; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* Using monitor modes and buffer at the same time is 17362306a36Sopenharmony_ci currently not supported */ 17462306a36Sopenharmony_ci bool monitor_on; 17562306a36Sopenharmony_ci unsigned int monitor_speed:3; 17662306a36Sopenharmony_ci u8 mask_high; 17762306a36Sopenharmony_ci u8 mask_low; 17862306a36Sopenharmony_ci /* 4x unipolar first then the fours bipolar ones */ 17962306a36Sopenharmony_ci s16 thresh_high[8]; 18062306a36Sopenharmony_ci s16 thresh_low[8]; 18162306a36Sopenharmony_ci struct regulator *vref; 18262306a36Sopenharmony_ci u32 vref_uv; 18362306a36Sopenharmony_ci int (*send)(const struct i2c_client *client, 18462306a36Sopenharmony_ci const char *buf, int count); 18562306a36Sopenharmony_ci int (*recv)(const struct i2c_client *client, 18662306a36Sopenharmony_ci char *buf, int count); 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci#define MAX1363_MODE_SINGLE(_num, _mask) { \ 19062306a36Sopenharmony_ci .conf = MAX1363_CHANNEL_SEL(_num) \ 19162306a36Sopenharmony_ci | MAX1363_CONFIG_SCAN_SINGLE_1 \ 19262306a36Sopenharmony_ci | MAX1363_CONFIG_SE, \ 19362306a36Sopenharmony_ci .modemask[0] = _mask, \ 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ 19762306a36Sopenharmony_ci .conf = MAX1363_CHANNEL_SEL(_num) \ 19862306a36Sopenharmony_ci | MAX1363_CONFIG_SCAN_TO_CS \ 19962306a36Sopenharmony_ci | MAX1363_CONFIG_SE, \ 20062306a36Sopenharmony_ci .modemask[0] = _mask, \ 20162306a36Sopenharmony_ci } 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci/* note not available for max1363 hence naming */ 20462306a36Sopenharmony_ci#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \ 20562306a36Sopenharmony_ci .conf = MAX1363_CHANNEL_SEL(_num) \ 20662306a36Sopenharmony_ci | MAX1236_SCAN_MID_TO_CHANNEL \ 20762306a36Sopenharmony_ci | MAX1363_CONFIG_SE, \ 20862306a36Sopenharmony_ci .modemask[0] = _mask \ 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ 21262306a36Sopenharmony_ci .conf = MAX1363_CHANNEL_SEL(_nump) \ 21362306a36Sopenharmony_ci | MAX1363_CONFIG_SCAN_SINGLE_1 \ 21462306a36Sopenharmony_ci | MAX1363_CONFIG_DE, \ 21562306a36Sopenharmony_ci .modemask[0] = _mask \ 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci/* Can't think how to automate naming so specify for now */ 21962306a36Sopenharmony_ci#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \ 22062306a36Sopenharmony_ci .conf = MAX1363_CHANNEL_SEL(_num) \ 22162306a36Sopenharmony_ci | MAX1363_CONFIG_SCAN_TO_CS \ 22262306a36Sopenharmony_ci | MAX1363_CONFIG_DE, \ 22362306a36Sopenharmony_ci .modemask[0] = _mask \ 22462306a36Sopenharmony_ci } 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci/* note only available for max1363 hence naming */ 22762306a36Sopenharmony_ci#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \ 22862306a36Sopenharmony_ci .conf = MAX1363_CHANNEL_SEL(_num) \ 22962306a36Sopenharmony_ci | MAX1236_SCAN_MID_TO_CHANNEL \ 23062306a36Sopenharmony_ci | MAX1363_CONFIG_SE, \ 23162306a36Sopenharmony_ci .modemask[0] = _mask \ 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic const struct max1363_mode max1363_mode_table[] = { 23562306a36Sopenharmony_ci /* All of the single channel options first */ 23662306a36Sopenharmony_ci MAX1363_MODE_SINGLE(0, 1 << 0), 23762306a36Sopenharmony_ci MAX1363_MODE_SINGLE(1, 1 << 1), 23862306a36Sopenharmony_ci MAX1363_MODE_SINGLE(2, 1 << 2), 23962306a36Sopenharmony_ci MAX1363_MODE_SINGLE(3, 1 << 3), 24062306a36Sopenharmony_ci MAX1363_MODE_SINGLE(4, 1 << 4), 24162306a36Sopenharmony_ci MAX1363_MODE_SINGLE(5, 1 << 5), 24262306a36Sopenharmony_ci MAX1363_MODE_SINGLE(6, 1 << 6), 24362306a36Sopenharmony_ci MAX1363_MODE_SINGLE(7, 1 << 7), 24462306a36Sopenharmony_ci MAX1363_MODE_SINGLE(8, 1 << 8), 24562306a36Sopenharmony_ci MAX1363_MODE_SINGLE(9, 1 << 9), 24662306a36Sopenharmony_ci MAX1363_MODE_SINGLE(10, 1 << 10), 24762306a36Sopenharmony_ci MAX1363_MODE_SINGLE(11, 1 << 11), 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), 25062306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), 25162306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), 25262306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), 25362306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), 25462306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), 25562306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), 25662306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), 25762306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), 25862306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), 25962306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), 26062306a36Sopenharmony_ci MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci /* The multichannel scans next */ 26362306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003), 26462306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007), 26562306a36Sopenharmony_ci MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C), 26662306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F), 26762306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F), 26862306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F), 26962306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F), 27062306a36Sopenharmony_ci MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0), 27162306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF), 27262306a36Sopenharmony_ci MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0), 27362306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF), 27462306a36Sopenharmony_ci MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0), 27562306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF), 27662306a36Sopenharmony_ci MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0), 27762306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF), 27862306a36Sopenharmony_ci MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0), 27962306a36Sopenharmony_ci MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF), 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000), 28262306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000), 28362306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000), 28462306a36Sopenharmony_ci MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000), 28562306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000), 28662306a36Sopenharmony_ci MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000), 28762306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000), 28862306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000), 28962306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000), 29062306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000), 29162306a36Sopenharmony_ci MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000), 29262306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000), 29362306a36Sopenharmony_ci MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000), 29462306a36Sopenharmony_ci MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000), 29562306a36Sopenharmony_ci}; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic const struct max1363_mode 29862306a36Sopenharmony_ci*max1363_match_mode(const unsigned long *mask, 29962306a36Sopenharmony_ci const struct max1363_chip_info *ci) 30062306a36Sopenharmony_ci{ 30162306a36Sopenharmony_ci int i; 30262306a36Sopenharmony_ci if (mask) 30362306a36Sopenharmony_ci for (i = 0; i < ci->num_modes; i++) 30462306a36Sopenharmony_ci if (bitmap_subset(mask, 30562306a36Sopenharmony_ci max1363_mode_table[ci->mode_list[i]]. 30662306a36Sopenharmony_ci modemask, 30762306a36Sopenharmony_ci MAX1363_MAX_CHANNELS)) 30862306a36Sopenharmony_ci return &max1363_mode_table[ci->mode_list[i]]; 30962306a36Sopenharmony_ci return NULL; 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_cistatic int max1363_smbus_send(const struct i2c_client *client, const char *buf, 31362306a36Sopenharmony_ci int count) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci int i, err; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci for (i = err = 0; err == 0 && i < count; ++i) 31862306a36Sopenharmony_ci err = i2c_smbus_write_byte(client, buf[i]); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci return err ? err : count; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cistatic int max1363_smbus_recv(const struct i2c_client *client, char *buf, 32462306a36Sopenharmony_ci int count) 32562306a36Sopenharmony_ci{ 32662306a36Sopenharmony_ci int i, ret; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci for (i = 0; i < count; ++i) { 32962306a36Sopenharmony_ci ret = i2c_smbus_read_byte(client); 33062306a36Sopenharmony_ci if (ret < 0) 33162306a36Sopenharmony_ci return ret; 33262306a36Sopenharmony_ci buf[i] = ret; 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci return count; 33662306a36Sopenharmony_ci} 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cistatic int max1363_write_basic_config(struct max1363_state *st) 33962306a36Sopenharmony_ci{ 34062306a36Sopenharmony_ci u8 tx_buf[2] = { st->setupbyte, st->configbyte }; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci return st->send(st->client, tx_buf, 2); 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic int max1363_set_scan_mode(struct max1363_state *st) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK 34862306a36Sopenharmony_ci | MAX1363_SCAN_MASK 34962306a36Sopenharmony_ci | MAX1363_SE_DE_MASK); 35062306a36Sopenharmony_ci st->configbyte |= st->current_mode->conf; 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci return max1363_write_basic_config(st); 35362306a36Sopenharmony_ci} 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_cistatic int max1363_read_single_chan(struct iio_dev *indio_dev, 35662306a36Sopenharmony_ci struct iio_chan_spec const *chan, 35762306a36Sopenharmony_ci int *val, 35862306a36Sopenharmony_ci long m) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci int ret = 0; 36162306a36Sopenharmony_ci s32 data; 36262306a36Sopenharmony_ci u8 rxbuf[2]; 36362306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 36462306a36Sopenharmony_ci struct i2c_client *client = st->client; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci ret = iio_device_claim_direct_mode(indio_dev); 36762306a36Sopenharmony_ci if (ret) 36862306a36Sopenharmony_ci return ret; 36962306a36Sopenharmony_ci mutex_lock(&st->lock); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci /* 37262306a36Sopenharmony_ci * If monitor mode is enabled, the method for reading a single 37362306a36Sopenharmony_ci * channel will have to be rather different and has not yet 37462306a36Sopenharmony_ci * been implemented. 37562306a36Sopenharmony_ci * 37662306a36Sopenharmony_ci * Also, cannot read directly if buffered capture enabled. 37762306a36Sopenharmony_ci */ 37862306a36Sopenharmony_ci if (st->monitor_on) { 37962306a36Sopenharmony_ci ret = -EBUSY; 38062306a36Sopenharmony_ci goto error_ret; 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci /* Check to see if current scan mode is correct */ 38462306a36Sopenharmony_ci if (st->current_mode != &max1363_mode_table[chan->address]) { 38562306a36Sopenharmony_ci /* Update scan mode if needed */ 38662306a36Sopenharmony_ci st->current_mode = &max1363_mode_table[chan->address]; 38762306a36Sopenharmony_ci ret = max1363_set_scan_mode(st); 38862306a36Sopenharmony_ci if (ret < 0) 38962306a36Sopenharmony_ci goto error_ret; 39062306a36Sopenharmony_ci } 39162306a36Sopenharmony_ci if (st->chip_info->bits != 8) { 39262306a36Sopenharmony_ci /* Get reading */ 39362306a36Sopenharmony_ci data = st->recv(client, rxbuf, 2); 39462306a36Sopenharmony_ci if (data < 0) { 39562306a36Sopenharmony_ci ret = data; 39662306a36Sopenharmony_ci goto error_ret; 39762306a36Sopenharmony_ci } 39862306a36Sopenharmony_ci data = (rxbuf[1] | rxbuf[0] << 8) & 39962306a36Sopenharmony_ci ((1 << st->chip_info->bits) - 1); 40062306a36Sopenharmony_ci } else { 40162306a36Sopenharmony_ci /* Get reading */ 40262306a36Sopenharmony_ci data = st->recv(client, rxbuf, 1); 40362306a36Sopenharmony_ci if (data < 0) { 40462306a36Sopenharmony_ci ret = data; 40562306a36Sopenharmony_ci goto error_ret; 40662306a36Sopenharmony_ci } 40762306a36Sopenharmony_ci data = rxbuf[0]; 40862306a36Sopenharmony_ci } 40962306a36Sopenharmony_ci *val = data; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_cierror_ret: 41262306a36Sopenharmony_ci mutex_unlock(&st->lock); 41362306a36Sopenharmony_ci iio_device_release_direct_mode(indio_dev); 41462306a36Sopenharmony_ci return ret; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci} 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_cistatic int max1363_read_raw(struct iio_dev *indio_dev, 41962306a36Sopenharmony_ci struct iio_chan_spec const *chan, 42062306a36Sopenharmony_ci int *val, 42162306a36Sopenharmony_ci int *val2, 42262306a36Sopenharmony_ci long m) 42362306a36Sopenharmony_ci{ 42462306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 42562306a36Sopenharmony_ci int ret; 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci switch (m) { 42862306a36Sopenharmony_ci case IIO_CHAN_INFO_RAW: 42962306a36Sopenharmony_ci ret = max1363_read_single_chan(indio_dev, chan, val, m); 43062306a36Sopenharmony_ci if (ret < 0) 43162306a36Sopenharmony_ci return ret; 43262306a36Sopenharmony_ci return IIO_VAL_INT; 43362306a36Sopenharmony_ci case IIO_CHAN_INFO_SCALE: 43462306a36Sopenharmony_ci *val = st->vref_uv / 1000; 43562306a36Sopenharmony_ci *val2 = st->chip_info->bits; 43662306a36Sopenharmony_ci return IIO_VAL_FRACTIONAL_LOG2; 43762306a36Sopenharmony_ci default: 43862306a36Sopenharmony_ci return -EINVAL; 43962306a36Sopenharmony_ci } 44062306a36Sopenharmony_ci return 0; 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci/* Applies to max1363 */ 44462306a36Sopenharmony_cistatic const enum max1363_modes max1363_mode_list[] = { 44562306a36Sopenharmony_ci _s0, _s1, _s2, _s3, 44662306a36Sopenharmony_ci s0to1, s0to2, s0to3, 44762306a36Sopenharmony_ci d0m1, d2m3, d1m0, d3m2, 44862306a36Sopenharmony_ci d0m1to2m3, d1m0to3m2, 44962306a36Sopenharmony_ci}; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistatic const struct iio_event_spec max1363_events[] = { 45262306a36Sopenharmony_ci { 45362306a36Sopenharmony_ci .type = IIO_EV_TYPE_THRESH, 45462306a36Sopenharmony_ci .dir = IIO_EV_DIR_RISING, 45562306a36Sopenharmony_ci .mask_separate = BIT(IIO_EV_INFO_VALUE) | 45662306a36Sopenharmony_ci BIT(IIO_EV_INFO_ENABLE), 45762306a36Sopenharmony_ci }, { 45862306a36Sopenharmony_ci .type = IIO_EV_TYPE_THRESH, 45962306a36Sopenharmony_ci .dir = IIO_EV_DIR_FALLING, 46062306a36Sopenharmony_ci .mask_separate = BIT(IIO_EV_INFO_VALUE) | 46162306a36Sopenharmony_ci BIT(IIO_EV_INFO_ENABLE), 46262306a36Sopenharmony_ci }, 46362306a36Sopenharmony_ci}; 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci#define MAX1363_CHAN_U(num, addr, si, bits, ev_spec, num_ev_spec) \ 46662306a36Sopenharmony_ci { \ 46762306a36Sopenharmony_ci .type = IIO_VOLTAGE, \ 46862306a36Sopenharmony_ci .indexed = 1, \ 46962306a36Sopenharmony_ci .channel = num, \ 47062306a36Sopenharmony_ci .address = addr, \ 47162306a36Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 47262306a36Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 47362306a36Sopenharmony_ci .datasheet_name = "AIN"#num, \ 47462306a36Sopenharmony_ci .scan_type = { \ 47562306a36Sopenharmony_ci .sign = 'u', \ 47662306a36Sopenharmony_ci .realbits = bits, \ 47762306a36Sopenharmony_ci .storagebits = (bits > 8) ? 16 : 8, \ 47862306a36Sopenharmony_ci .endianness = IIO_BE, \ 47962306a36Sopenharmony_ci }, \ 48062306a36Sopenharmony_ci .scan_index = si, \ 48162306a36Sopenharmony_ci .event_spec = ev_spec, \ 48262306a36Sopenharmony_ci .num_event_specs = num_ev_spec, \ 48362306a36Sopenharmony_ci } 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci/* bipolar channel */ 48662306a36Sopenharmony_ci#define MAX1363_CHAN_B(num, num2, addr, si, bits, ev_spec, num_ev_spec) \ 48762306a36Sopenharmony_ci { \ 48862306a36Sopenharmony_ci .type = IIO_VOLTAGE, \ 48962306a36Sopenharmony_ci .differential = 1, \ 49062306a36Sopenharmony_ci .indexed = 1, \ 49162306a36Sopenharmony_ci .channel = num, \ 49262306a36Sopenharmony_ci .channel2 = num2, \ 49362306a36Sopenharmony_ci .address = addr, \ 49462306a36Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 49562306a36Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 49662306a36Sopenharmony_ci .datasheet_name = "AIN"#num"-AIN"#num2, \ 49762306a36Sopenharmony_ci .scan_type = { \ 49862306a36Sopenharmony_ci .sign = 's', \ 49962306a36Sopenharmony_ci .realbits = bits, \ 50062306a36Sopenharmony_ci .storagebits = (bits > 8) ? 16 : 8, \ 50162306a36Sopenharmony_ci .endianness = IIO_BE, \ 50262306a36Sopenharmony_ci }, \ 50362306a36Sopenharmony_ci .scan_index = si, \ 50462306a36Sopenharmony_ci .event_spec = ev_spec, \ 50562306a36Sopenharmony_ci .num_event_specs = num_ev_spec, \ 50662306a36Sopenharmony_ci } 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci#define MAX1363_4X_CHANS(bits, ev_spec, num_ev_spec) { \ 50962306a36Sopenharmony_ci MAX1363_CHAN_U(0, _s0, 0, bits, ev_spec, num_ev_spec), \ 51062306a36Sopenharmony_ci MAX1363_CHAN_U(1, _s1, 1, bits, ev_spec, num_ev_spec), \ 51162306a36Sopenharmony_ci MAX1363_CHAN_U(2, _s2, 2, bits, ev_spec, num_ev_spec), \ 51262306a36Sopenharmony_ci MAX1363_CHAN_U(3, _s3, 3, bits, ev_spec, num_ev_spec), \ 51362306a36Sopenharmony_ci MAX1363_CHAN_B(0, 1, d0m1, 4, bits, ev_spec, num_ev_spec), \ 51462306a36Sopenharmony_ci MAX1363_CHAN_B(2, 3, d2m3, 5, bits, ev_spec, num_ev_spec), \ 51562306a36Sopenharmony_ci MAX1363_CHAN_B(1, 0, d1m0, 6, bits, ev_spec, num_ev_spec), \ 51662306a36Sopenharmony_ci MAX1363_CHAN_B(3, 2, d3m2, 7, bits, ev_spec, num_ev_spec), \ 51762306a36Sopenharmony_ci IIO_CHAN_SOFT_TIMESTAMP(8) \ 51862306a36Sopenharmony_ci } 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_cistatic const struct iio_chan_spec max1036_channels[] = 52162306a36Sopenharmony_ci MAX1363_4X_CHANS(8, NULL, 0); 52262306a36Sopenharmony_cistatic const struct iio_chan_spec max1136_channels[] = 52362306a36Sopenharmony_ci MAX1363_4X_CHANS(10, NULL, 0); 52462306a36Sopenharmony_cistatic const struct iio_chan_spec max1236_channels[] = 52562306a36Sopenharmony_ci MAX1363_4X_CHANS(12, NULL, 0); 52662306a36Sopenharmony_cistatic const struct iio_chan_spec max1361_channels[] = 52762306a36Sopenharmony_ci MAX1363_4X_CHANS(10, max1363_events, ARRAY_SIZE(max1363_events)); 52862306a36Sopenharmony_cistatic const struct iio_chan_spec max1363_channels[] = 52962306a36Sopenharmony_ci MAX1363_4X_CHANS(12, max1363_events, ARRAY_SIZE(max1363_events)); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci/* Applies to max1236, max1237 */ 53262306a36Sopenharmony_cistatic const enum max1363_modes max1236_mode_list[] = { 53362306a36Sopenharmony_ci _s0, _s1, _s2, _s3, 53462306a36Sopenharmony_ci s0to1, s0to2, s0to3, 53562306a36Sopenharmony_ci d0m1, d2m3, d1m0, d3m2, 53662306a36Sopenharmony_ci d0m1to2m3, d1m0to3m2, 53762306a36Sopenharmony_ci s2to3, 53862306a36Sopenharmony_ci}; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci/* Applies to max1238, max1239 */ 54162306a36Sopenharmony_cistatic const enum max1363_modes max1238_mode_list[] = { 54262306a36Sopenharmony_ci _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, 54362306a36Sopenharmony_ci s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, 54462306a36Sopenharmony_ci s0to7, s0to8, s0to9, s0to10, s0to11, 54562306a36Sopenharmony_ci d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, 54662306a36Sopenharmony_ci d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, 54762306a36Sopenharmony_ci d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, 54862306a36Sopenharmony_ci d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, 54962306a36Sopenharmony_ci s6to7, s6to8, s6to9, s6to10, s6to11, 55062306a36Sopenharmony_ci d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, 55162306a36Sopenharmony_ci}; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci#define MAX1363_12X_CHANS(bits) { \ 55462306a36Sopenharmony_ci MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0), \ 55562306a36Sopenharmony_ci MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0), \ 55662306a36Sopenharmony_ci MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0), \ 55762306a36Sopenharmony_ci MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0), \ 55862306a36Sopenharmony_ci MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0), \ 55962306a36Sopenharmony_ci MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0), \ 56062306a36Sopenharmony_ci MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0), \ 56162306a36Sopenharmony_ci MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0), \ 56262306a36Sopenharmony_ci MAX1363_CHAN_U(8, _s8, 8, bits, NULL, 0), \ 56362306a36Sopenharmony_ci MAX1363_CHAN_U(9, _s9, 9, bits, NULL, 0), \ 56462306a36Sopenharmony_ci MAX1363_CHAN_U(10, _s10, 10, bits, NULL, 0), \ 56562306a36Sopenharmony_ci MAX1363_CHAN_U(11, _s11, 11, bits, NULL, 0), \ 56662306a36Sopenharmony_ci MAX1363_CHAN_B(0, 1, d0m1, 12, bits, NULL, 0), \ 56762306a36Sopenharmony_ci MAX1363_CHAN_B(2, 3, d2m3, 13, bits, NULL, 0), \ 56862306a36Sopenharmony_ci MAX1363_CHAN_B(4, 5, d4m5, 14, bits, NULL, 0), \ 56962306a36Sopenharmony_ci MAX1363_CHAN_B(6, 7, d6m7, 15, bits, NULL, 0), \ 57062306a36Sopenharmony_ci MAX1363_CHAN_B(8, 9, d8m9, 16, bits, NULL, 0), \ 57162306a36Sopenharmony_ci MAX1363_CHAN_B(10, 11, d10m11, 17, bits, NULL, 0), \ 57262306a36Sopenharmony_ci MAX1363_CHAN_B(1, 0, d1m0, 18, bits, NULL, 0), \ 57362306a36Sopenharmony_ci MAX1363_CHAN_B(3, 2, d3m2, 19, bits, NULL, 0), \ 57462306a36Sopenharmony_ci MAX1363_CHAN_B(5, 4, d5m4, 20, bits, NULL, 0), \ 57562306a36Sopenharmony_ci MAX1363_CHAN_B(7, 6, d7m6, 21, bits, NULL, 0), \ 57662306a36Sopenharmony_ci MAX1363_CHAN_B(9, 8, d9m8, 22, bits, NULL, 0), \ 57762306a36Sopenharmony_ci MAX1363_CHAN_B(11, 10, d11m10, 23, bits, NULL, 0), \ 57862306a36Sopenharmony_ci IIO_CHAN_SOFT_TIMESTAMP(24) \ 57962306a36Sopenharmony_ci } 58062306a36Sopenharmony_cistatic const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); 58162306a36Sopenharmony_cistatic const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); 58262306a36Sopenharmony_cistatic const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_cistatic const enum max1363_modes max11607_mode_list[] = { 58562306a36Sopenharmony_ci _s0, _s1, _s2, _s3, 58662306a36Sopenharmony_ci s0to1, s0to2, s0to3, 58762306a36Sopenharmony_ci s2to3, 58862306a36Sopenharmony_ci d0m1, d2m3, d1m0, d3m2, 58962306a36Sopenharmony_ci d0m1to2m3, d1m0to3m2, 59062306a36Sopenharmony_ci}; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistatic const enum max1363_modes max11608_mode_list[] = { 59362306a36Sopenharmony_ci _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, 59462306a36Sopenharmony_ci s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, 59562306a36Sopenharmony_ci s6to7, 59662306a36Sopenharmony_ci d0m1, d2m3, d4m5, d6m7, 59762306a36Sopenharmony_ci d1m0, d3m2, d5m4, d7m6, 59862306a36Sopenharmony_ci d0m1to2m3, d0m1to4m5, d0m1to6m7, 59962306a36Sopenharmony_ci d1m0to3m2, d1m0to5m4, d1m0to7m6, 60062306a36Sopenharmony_ci}; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci#define MAX1363_8X_CHANS(bits) { \ 60362306a36Sopenharmony_ci MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0), \ 60462306a36Sopenharmony_ci MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0), \ 60562306a36Sopenharmony_ci MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0), \ 60662306a36Sopenharmony_ci MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0), \ 60762306a36Sopenharmony_ci MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0), \ 60862306a36Sopenharmony_ci MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0), \ 60962306a36Sopenharmony_ci MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0), \ 61062306a36Sopenharmony_ci MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0), \ 61162306a36Sopenharmony_ci MAX1363_CHAN_B(0, 1, d0m1, 8, bits, NULL, 0), \ 61262306a36Sopenharmony_ci MAX1363_CHAN_B(2, 3, d2m3, 9, bits, NULL, 0), \ 61362306a36Sopenharmony_ci MAX1363_CHAN_B(4, 5, d4m5, 10, bits, NULL, 0), \ 61462306a36Sopenharmony_ci MAX1363_CHAN_B(6, 7, d6m7, 11, bits, NULL, 0), \ 61562306a36Sopenharmony_ci MAX1363_CHAN_B(1, 0, d1m0, 12, bits, NULL, 0), \ 61662306a36Sopenharmony_ci MAX1363_CHAN_B(3, 2, d3m2, 13, bits, NULL, 0), \ 61762306a36Sopenharmony_ci MAX1363_CHAN_B(5, 4, d5m4, 14, bits, NULL, 0), \ 61862306a36Sopenharmony_ci MAX1363_CHAN_B(7, 6, d7m6, 15, bits, NULL, 0), \ 61962306a36Sopenharmony_ci IIO_CHAN_SOFT_TIMESTAMP(16) \ 62062306a36Sopenharmony_ci} 62162306a36Sopenharmony_cistatic const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); 62262306a36Sopenharmony_cistatic const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); 62362306a36Sopenharmony_cistatic const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_cistatic const enum max1363_modes max11644_mode_list[] = { 62662306a36Sopenharmony_ci _s0, _s1, s0to1, d0m1, d1m0, 62762306a36Sopenharmony_ci}; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci#define MAX1363_2X_CHANS(bits) { \ 63062306a36Sopenharmony_ci MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0), \ 63162306a36Sopenharmony_ci MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0), \ 63262306a36Sopenharmony_ci MAX1363_CHAN_B(0, 1, d0m1, 2, bits, NULL, 0), \ 63362306a36Sopenharmony_ci MAX1363_CHAN_B(1, 0, d1m0, 3, bits, NULL, 0), \ 63462306a36Sopenharmony_ci IIO_CHAN_SOFT_TIMESTAMP(4) \ 63562306a36Sopenharmony_ci } 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_cistatic const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); 63862306a36Sopenharmony_cistatic const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_cienum { max1361, 64162306a36Sopenharmony_ci max1362, 64262306a36Sopenharmony_ci max1363, 64362306a36Sopenharmony_ci max1364, 64462306a36Sopenharmony_ci max1036, 64562306a36Sopenharmony_ci max1037, 64662306a36Sopenharmony_ci max1038, 64762306a36Sopenharmony_ci max1039, 64862306a36Sopenharmony_ci max1136, 64962306a36Sopenharmony_ci max1137, 65062306a36Sopenharmony_ci max1138, 65162306a36Sopenharmony_ci max1139, 65262306a36Sopenharmony_ci max1236, 65362306a36Sopenharmony_ci max1237, 65462306a36Sopenharmony_ci max1238, 65562306a36Sopenharmony_ci max1239, 65662306a36Sopenharmony_ci max11600, 65762306a36Sopenharmony_ci max11601, 65862306a36Sopenharmony_ci max11602, 65962306a36Sopenharmony_ci max11603, 66062306a36Sopenharmony_ci max11604, 66162306a36Sopenharmony_ci max11605, 66262306a36Sopenharmony_ci max11606, 66362306a36Sopenharmony_ci max11607, 66462306a36Sopenharmony_ci max11608, 66562306a36Sopenharmony_ci max11609, 66662306a36Sopenharmony_ci max11610, 66762306a36Sopenharmony_ci max11611, 66862306a36Sopenharmony_ci max11612, 66962306a36Sopenharmony_ci max11613, 67062306a36Sopenharmony_ci max11614, 67162306a36Sopenharmony_ci max11615, 67262306a36Sopenharmony_ci max11616, 67362306a36Sopenharmony_ci max11617, 67462306a36Sopenharmony_ci max11644, 67562306a36Sopenharmony_ci max11645, 67662306a36Sopenharmony_ci max11646, 67762306a36Sopenharmony_ci max11647 67862306a36Sopenharmony_ci}; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_cistatic const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600, 68162306a36Sopenharmony_ci 8300, 4200, 2000, 1000 }; 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_cistatic ssize_t max1363_monitor_show_freq(struct device *dev, 68462306a36Sopenharmony_ci struct device_attribute *attr, 68562306a36Sopenharmony_ci char *buf) 68662306a36Sopenharmony_ci{ 68762306a36Sopenharmony_ci struct max1363_state *st = iio_priv(dev_to_iio_dev(dev)); 68862306a36Sopenharmony_ci return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]); 68962306a36Sopenharmony_ci} 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_cistatic ssize_t max1363_monitor_store_freq(struct device *dev, 69262306a36Sopenharmony_ci struct device_attribute *attr, 69362306a36Sopenharmony_ci const char *buf, 69462306a36Sopenharmony_ci size_t len) 69562306a36Sopenharmony_ci{ 69662306a36Sopenharmony_ci struct iio_dev *indio_dev = dev_to_iio_dev(dev); 69762306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 69862306a36Sopenharmony_ci int i, ret; 69962306a36Sopenharmony_ci unsigned long val; 70062306a36Sopenharmony_ci bool found = false; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci ret = kstrtoul(buf, 10, &val); 70362306a36Sopenharmony_ci if (ret) 70462306a36Sopenharmony_ci return -EINVAL; 70562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++) 70662306a36Sopenharmony_ci if (val == max1363_monitor_speeds[i]) { 70762306a36Sopenharmony_ci found = true; 70862306a36Sopenharmony_ci break; 70962306a36Sopenharmony_ci } 71062306a36Sopenharmony_ci if (!found) 71162306a36Sopenharmony_ci return -EINVAL; 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci mutex_lock(&st->lock); 71462306a36Sopenharmony_ci st->monitor_speed = i; 71562306a36Sopenharmony_ci mutex_unlock(&st->lock); 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci return 0; 71862306a36Sopenharmony_ci} 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_cistatic IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, 72162306a36Sopenharmony_ci max1363_monitor_show_freq, 72262306a36Sopenharmony_ci max1363_monitor_store_freq); 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_cistatic IIO_CONST_ATTR(sampling_frequency_available, 72562306a36Sopenharmony_ci "133000 665000 33300 16600 8300 4200 2000 1000"); 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_cistatic int max1363_read_thresh(struct iio_dev *indio_dev, 72862306a36Sopenharmony_ci const struct iio_chan_spec *chan, enum iio_event_type type, 72962306a36Sopenharmony_ci enum iio_event_direction dir, enum iio_event_info info, int *val, 73062306a36Sopenharmony_ci int *val2) 73162306a36Sopenharmony_ci{ 73262306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 73362306a36Sopenharmony_ci if (dir == IIO_EV_DIR_FALLING) 73462306a36Sopenharmony_ci *val = st->thresh_low[chan->channel]; 73562306a36Sopenharmony_ci else 73662306a36Sopenharmony_ci *val = st->thresh_high[chan->channel]; 73762306a36Sopenharmony_ci return IIO_VAL_INT; 73862306a36Sopenharmony_ci} 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_cistatic int max1363_write_thresh(struct iio_dev *indio_dev, 74162306a36Sopenharmony_ci const struct iio_chan_spec *chan, enum iio_event_type type, 74262306a36Sopenharmony_ci enum iio_event_direction dir, enum iio_event_info info, int val, 74362306a36Sopenharmony_ci int val2) 74462306a36Sopenharmony_ci{ 74562306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 74662306a36Sopenharmony_ci /* make it handle signed correctly as well */ 74762306a36Sopenharmony_ci switch (st->chip_info->bits) { 74862306a36Sopenharmony_ci case 10: 74962306a36Sopenharmony_ci if (val > 0x3FF) 75062306a36Sopenharmony_ci return -EINVAL; 75162306a36Sopenharmony_ci break; 75262306a36Sopenharmony_ci case 12: 75362306a36Sopenharmony_ci if (val > 0xFFF) 75462306a36Sopenharmony_ci return -EINVAL; 75562306a36Sopenharmony_ci break; 75662306a36Sopenharmony_ci } 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci switch (dir) { 75962306a36Sopenharmony_ci case IIO_EV_DIR_FALLING: 76062306a36Sopenharmony_ci st->thresh_low[chan->channel] = val; 76162306a36Sopenharmony_ci break; 76262306a36Sopenharmony_ci case IIO_EV_DIR_RISING: 76362306a36Sopenharmony_ci st->thresh_high[chan->channel] = val; 76462306a36Sopenharmony_ci break; 76562306a36Sopenharmony_ci default: 76662306a36Sopenharmony_ci return -EINVAL; 76762306a36Sopenharmony_ci } 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci return 0; 77062306a36Sopenharmony_ci} 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_cistatic const u64 max1363_event_codes[] = { 77362306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, 77462306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), 77562306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, 77662306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), 77762306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, 77862306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), 77962306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, 78062306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), 78162306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, 78262306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 78362306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, 78462306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 78562306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, 78662306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 78762306a36Sopenharmony_ci IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, 78862306a36Sopenharmony_ci IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 78962306a36Sopenharmony_ci}; 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_cistatic irqreturn_t max1363_event_handler(int irq, void *private) 79262306a36Sopenharmony_ci{ 79362306a36Sopenharmony_ci struct iio_dev *indio_dev = private; 79462306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 79562306a36Sopenharmony_ci s64 timestamp = iio_get_time_ns(indio_dev); 79662306a36Sopenharmony_ci unsigned long mask, loc; 79762306a36Sopenharmony_ci u8 rx; 79862306a36Sopenharmony_ci u8 tx[2] = { st->setupbyte, 79962306a36Sopenharmony_ci MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 }; 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci st->recv(st->client, &rx, 1); 80262306a36Sopenharmony_ci mask = rx; 80362306a36Sopenharmony_ci for_each_set_bit(loc, &mask, 8) 80462306a36Sopenharmony_ci iio_push_event(indio_dev, max1363_event_codes[loc], timestamp); 80562306a36Sopenharmony_ci st->send(st->client, tx, 2); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci return IRQ_HANDLED; 80862306a36Sopenharmony_ci} 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_cistatic int max1363_read_event_config(struct iio_dev *indio_dev, 81162306a36Sopenharmony_ci const struct iio_chan_spec *chan, enum iio_event_type type, 81262306a36Sopenharmony_ci enum iio_event_direction dir) 81362306a36Sopenharmony_ci{ 81462306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 81562306a36Sopenharmony_ci int val; 81662306a36Sopenharmony_ci int number = chan->channel; 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci mutex_lock(&st->lock); 81962306a36Sopenharmony_ci if (dir == IIO_EV_DIR_FALLING) 82062306a36Sopenharmony_ci val = (1 << number) & st->mask_low; 82162306a36Sopenharmony_ci else 82262306a36Sopenharmony_ci val = (1 << number) & st->mask_high; 82362306a36Sopenharmony_ci mutex_unlock(&st->lock); 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci return val; 82662306a36Sopenharmony_ci} 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_cistatic int max1363_monitor_mode_update(struct max1363_state *st, int enabled) 82962306a36Sopenharmony_ci{ 83062306a36Sopenharmony_ci u8 *tx_buf; 83162306a36Sopenharmony_ci int ret, i = 3, j; 83262306a36Sopenharmony_ci unsigned long numelements; 83362306a36Sopenharmony_ci int len; 83462306a36Sopenharmony_ci const long *modemask; 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci if (!enabled) { 83762306a36Sopenharmony_ci /* transition to buffered capture is not currently supported */ 83862306a36Sopenharmony_ci st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP; 83962306a36Sopenharmony_ci st->configbyte &= ~MAX1363_SCAN_MASK; 84062306a36Sopenharmony_ci st->monitor_on = false; 84162306a36Sopenharmony_ci return max1363_write_basic_config(st); 84262306a36Sopenharmony_ci } 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci /* Ensure we are in the relevant mode */ 84562306a36Sopenharmony_ci st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP; 84662306a36Sopenharmony_ci st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK 84762306a36Sopenharmony_ci | MAX1363_SCAN_MASK 84862306a36Sopenharmony_ci | MAX1363_SE_DE_MASK); 84962306a36Sopenharmony_ci st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE; 85062306a36Sopenharmony_ci if ((st->mask_low | st->mask_high) & 0x0F) { 85162306a36Sopenharmony_ci st->configbyte |= max1363_mode_table[s0to3].conf; 85262306a36Sopenharmony_ci modemask = max1363_mode_table[s0to3].modemask; 85362306a36Sopenharmony_ci } else if ((st->mask_low | st->mask_high) & 0x30) { 85462306a36Sopenharmony_ci st->configbyte |= max1363_mode_table[d0m1to2m3].conf; 85562306a36Sopenharmony_ci modemask = max1363_mode_table[d0m1to2m3].modemask; 85662306a36Sopenharmony_ci } else { 85762306a36Sopenharmony_ci st->configbyte |= max1363_mode_table[d1m0to3m2].conf; 85862306a36Sopenharmony_ci modemask = max1363_mode_table[d1m0to3m2].modemask; 85962306a36Sopenharmony_ci } 86062306a36Sopenharmony_ci numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS); 86162306a36Sopenharmony_ci len = 3 * numelements + 3; 86262306a36Sopenharmony_ci tx_buf = kmalloc(len, GFP_KERNEL); 86362306a36Sopenharmony_ci if (!tx_buf) { 86462306a36Sopenharmony_ci ret = -ENOMEM; 86562306a36Sopenharmony_ci goto error_ret; 86662306a36Sopenharmony_ci } 86762306a36Sopenharmony_ci tx_buf[0] = st->configbyte; 86862306a36Sopenharmony_ci tx_buf[1] = st->setupbyte; 86962306a36Sopenharmony_ci tx_buf[2] = (st->monitor_speed << 1); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci /* 87262306a36Sopenharmony_ci * So we need to do yet another bit of nefarious scan mode 87362306a36Sopenharmony_ci * setup to match what we need. 87462306a36Sopenharmony_ci */ 87562306a36Sopenharmony_ci for (j = 0; j < 8; j++) 87662306a36Sopenharmony_ci if (test_bit(j, modemask)) { 87762306a36Sopenharmony_ci /* Establish the mode is in the scan */ 87862306a36Sopenharmony_ci if (st->mask_low & (1 << j)) { 87962306a36Sopenharmony_ci tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; 88062306a36Sopenharmony_ci tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0; 88162306a36Sopenharmony_ci } else if (j < 4) { 88262306a36Sopenharmony_ci tx_buf[i] = 0; 88362306a36Sopenharmony_ci tx_buf[i + 1] = 0; 88462306a36Sopenharmony_ci } else { 88562306a36Sopenharmony_ci tx_buf[i] = 0x80; 88662306a36Sopenharmony_ci tx_buf[i + 1] = 0; 88762306a36Sopenharmony_ci } 88862306a36Sopenharmony_ci if (st->mask_high & (1 << j)) { 88962306a36Sopenharmony_ci tx_buf[i + 1] |= 89062306a36Sopenharmony_ci (st->thresh_high[j] >> 8) & 0x0F; 89162306a36Sopenharmony_ci tx_buf[i + 2] = st->thresh_high[j] & 0xFF; 89262306a36Sopenharmony_ci } else if (j < 4) { 89362306a36Sopenharmony_ci tx_buf[i + 1] |= 0x0F; 89462306a36Sopenharmony_ci tx_buf[i + 2] = 0xFF; 89562306a36Sopenharmony_ci } else { 89662306a36Sopenharmony_ci tx_buf[i + 1] |= 0x07; 89762306a36Sopenharmony_ci tx_buf[i + 2] = 0xFF; 89862306a36Sopenharmony_ci } 89962306a36Sopenharmony_ci i += 3; 90062306a36Sopenharmony_ci } 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci ret = st->send(st->client, tx_buf, len); 90462306a36Sopenharmony_ci if (ret < 0) 90562306a36Sopenharmony_ci goto error_ret; 90662306a36Sopenharmony_ci if (ret != len) { 90762306a36Sopenharmony_ci ret = -EIO; 90862306a36Sopenharmony_ci goto error_ret; 90962306a36Sopenharmony_ci } 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ci /* 91262306a36Sopenharmony_ci * Now that we hopefully have sensible thresholds in place it is 91362306a36Sopenharmony_ci * time to turn the interrupts on. 91462306a36Sopenharmony_ci * It is unclear from the data sheet if this should be necessary 91562306a36Sopenharmony_ci * (i.e. whether monitor mode setup is atomic) but it appears to 91662306a36Sopenharmony_ci * be in practice. 91762306a36Sopenharmony_ci */ 91862306a36Sopenharmony_ci tx_buf[0] = st->setupbyte; 91962306a36Sopenharmony_ci tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0; 92062306a36Sopenharmony_ci ret = st->send(st->client, tx_buf, 2); 92162306a36Sopenharmony_ci if (ret < 0) 92262306a36Sopenharmony_ci goto error_ret; 92362306a36Sopenharmony_ci if (ret != 2) { 92462306a36Sopenharmony_ci ret = -EIO; 92562306a36Sopenharmony_ci goto error_ret; 92662306a36Sopenharmony_ci } 92762306a36Sopenharmony_ci ret = 0; 92862306a36Sopenharmony_ci st->monitor_on = true; 92962306a36Sopenharmony_cierror_ret: 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_ci kfree(tx_buf); 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci return ret; 93462306a36Sopenharmony_ci} 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci/* 93762306a36Sopenharmony_ci * To keep this manageable we always use one of 3 scan modes. 93862306a36Sopenharmony_ci * Scan 0...3, 0-1,2-3 and 1-0,3-2 93962306a36Sopenharmony_ci */ 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_cistatic inline int __max1363_check_event_mask(int thismask, int checkmask) 94262306a36Sopenharmony_ci{ 94362306a36Sopenharmony_ci int ret = 0; 94462306a36Sopenharmony_ci /* Is it unipolar */ 94562306a36Sopenharmony_ci if (thismask < 4) { 94662306a36Sopenharmony_ci if (checkmask & ~0x0F) { 94762306a36Sopenharmony_ci ret = -EBUSY; 94862306a36Sopenharmony_ci goto error_ret; 94962306a36Sopenharmony_ci } 95062306a36Sopenharmony_ci } else if (thismask < 6) { 95162306a36Sopenharmony_ci if (checkmask & ~0x30) { 95262306a36Sopenharmony_ci ret = -EBUSY; 95362306a36Sopenharmony_ci goto error_ret; 95462306a36Sopenharmony_ci } 95562306a36Sopenharmony_ci } else if (checkmask & ~0xC0) 95662306a36Sopenharmony_ci ret = -EBUSY; 95762306a36Sopenharmony_cierror_ret: 95862306a36Sopenharmony_ci return ret; 95962306a36Sopenharmony_ci} 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_cistatic int max1363_write_event_config(struct iio_dev *indio_dev, 96262306a36Sopenharmony_ci const struct iio_chan_spec *chan, enum iio_event_type type, 96362306a36Sopenharmony_ci enum iio_event_direction dir, int state) 96462306a36Sopenharmony_ci{ 96562306a36Sopenharmony_ci int ret = 0; 96662306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 96762306a36Sopenharmony_ci u16 unifiedmask; 96862306a36Sopenharmony_ci int number = chan->channel; 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci ret = iio_device_claim_direct_mode(indio_dev); 97162306a36Sopenharmony_ci if (ret) 97262306a36Sopenharmony_ci return ret; 97362306a36Sopenharmony_ci mutex_lock(&st->lock); 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci unifiedmask = st->mask_low | st->mask_high; 97662306a36Sopenharmony_ci if (dir == IIO_EV_DIR_FALLING) { 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci if (state == 0) 97962306a36Sopenharmony_ci st->mask_low &= ~(1 << number); 98062306a36Sopenharmony_ci else { 98162306a36Sopenharmony_ci ret = __max1363_check_event_mask((1 << number), 98262306a36Sopenharmony_ci unifiedmask); 98362306a36Sopenharmony_ci if (ret) 98462306a36Sopenharmony_ci goto error_ret; 98562306a36Sopenharmony_ci st->mask_low |= (1 << number); 98662306a36Sopenharmony_ci } 98762306a36Sopenharmony_ci } else { 98862306a36Sopenharmony_ci if (state == 0) 98962306a36Sopenharmony_ci st->mask_high &= ~(1 << number); 99062306a36Sopenharmony_ci else { 99162306a36Sopenharmony_ci ret = __max1363_check_event_mask((1 << number), 99262306a36Sopenharmony_ci unifiedmask); 99362306a36Sopenharmony_ci if (ret) 99462306a36Sopenharmony_ci goto error_ret; 99562306a36Sopenharmony_ci st->mask_high |= (1 << number); 99662306a36Sopenharmony_ci } 99762306a36Sopenharmony_ci } 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_ci max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low)); 100062306a36Sopenharmony_cierror_ret: 100162306a36Sopenharmony_ci mutex_unlock(&st->lock); 100262306a36Sopenharmony_ci iio_device_release_direct_mode(indio_dev); 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci return ret; 100562306a36Sopenharmony_ci} 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_ci/* 100862306a36Sopenharmony_ci * As with scan_elements, only certain sets of these can 100962306a36Sopenharmony_ci * be combined. 101062306a36Sopenharmony_ci */ 101162306a36Sopenharmony_cistatic struct attribute *max1363_event_attributes[] = { 101262306a36Sopenharmony_ci &iio_dev_attr_sampling_frequency.dev_attr.attr, 101362306a36Sopenharmony_ci &iio_const_attr_sampling_frequency_available.dev_attr.attr, 101462306a36Sopenharmony_ci NULL, 101562306a36Sopenharmony_ci}; 101662306a36Sopenharmony_ci 101762306a36Sopenharmony_cistatic const struct attribute_group max1363_event_attribute_group = { 101862306a36Sopenharmony_ci .attrs = max1363_event_attributes, 101962306a36Sopenharmony_ci}; 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_cistatic int max1363_update_scan_mode(struct iio_dev *indio_dev, 102262306a36Sopenharmony_ci const unsigned long *scan_mask) 102362306a36Sopenharmony_ci{ 102462306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci /* 102762306a36Sopenharmony_ci * Need to figure out the current mode based upon the requested 102862306a36Sopenharmony_ci * scan mask in iio_dev 102962306a36Sopenharmony_ci */ 103062306a36Sopenharmony_ci st->current_mode = max1363_match_mode(scan_mask, st->chip_info); 103162306a36Sopenharmony_ci if (!st->current_mode) 103262306a36Sopenharmony_ci return -EINVAL; 103362306a36Sopenharmony_ci max1363_set_scan_mode(st); 103462306a36Sopenharmony_ci return 0; 103562306a36Sopenharmony_ci} 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_cistatic const struct iio_info max1238_info = { 103862306a36Sopenharmony_ci .read_raw = &max1363_read_raw, 103962306a36Sopenharmony_ci .update_scan_mode = &max1363_update_scan_mode, 104062306a36Sopenharmony_ci}; 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_cistatic const struct iio_info max1363_info = { 104362306a36Sopenharmony_ci .read_event_value = &max1363_read_thresh, 104462306a36Sopenharmony_ci .write_event_value = &max1363_write_thresh, 104562306a36Sopenharmony_ci .read_event_config = &max1363_read_event_config, 104662306a36Sopenharmony_ci .write_event_config = &max1363_write_event_config, 104762306a36Sopenharmony_ci .read_raw = &max1363_read_raw, 104862306a36Sopenharmony_ci .update_scan_mode = &max1363_update_scan_mode, 104962306a36Sopenharmony_ci .event_attrs = &max1363_event_attribute_group, 105062306a36Sopenharmony_ci}; 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_ci/* max1363 and max1368 tested - rest from data sheet */ 105362306a36Sopenharmony_cistatic const struct max1363_chip_info max1363_chip_info_tbl[] = { 105462306a36Sopenharmony_ci [max1361] = { 105562306a36Sopenharmony_ci .bits = 10, 105662306a36Sopenharmony_ci .int_vref_mv = 2048, 105762306a36Sopenharmony_ci .mode_list = max1363_mode_list, 105862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1363_mode_list), 105962306a36Sopenharmony_ci .default_mode = s0to3, 106062306a36Sopenharmony_ci .channels = max1361_channels, 106162306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1361_channels), 106262306a36Sopenharmony_ci .info = &max1363_info, 106362306a36Sopenharmony_ci }, 106462306a36Sopenharmony_ci [max1362] = { 106562306a36Sopenharmony_ci .bits = 10, 106662306a36Sopenharmony_ci .int_vref_mv = 4096, 106762306a36Sopenharmony_ci .mode_list = max1363_mode_list, 106862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1363_mode_list), 106962306a36Sopenharmony_ci .default_mode = s0to3, 107062306a36Sopenharmony_ci .channels = max1361_channels, 107162306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1361_channels), 107262306a36Sopenharmony_ci .info = &max1363_info, 107362306a36Sopenharmony_ci }, 107462306a36Sopenharmony_ci [max1363] = { 107562306a36Sopenharmony_ci .bits = 12, 107662306a36Sopenharmony_ci .int_vref_mv = 2048, 107762306a36Sopenharmony_ci .mode_list = max1363_mode_list, 107862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1363_mode_list), 107962306a36Sopenharmony_ci .default_mode = s0to3, 108062306a36Sopenharmony_ci .channels = max1363_channels, 108162306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1363_channels), 108262306a36Sopenharmony_ci .info = &max1363_info, 108362306a36Sopenharmony_ci }, 108462306a36Sopenharmony_ci [max1364] = { 108562306a36Sopenharmony_ci .bits = 12, 108662306a36Sopenharmony_ci .int_vref_mv = 4096, 108762306a36Sopenharmony_ci .mode_list = max1363_mode_list, 108862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1363_mode_list), 108962306a36Sopenharmony_ci .default_mode = s0to3, 109062306a36Sopenharmony_ci .channels = max1363_channels, 109162306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1363_channels), 109262306a36Sopenharmony_ci .info = &max1363_info, 109362306a36Sopenharmony_ci }, 109462306a36Sopenharmony_ci [max1036] = { 109562306a36Sopenharmony_ci .bits = 8, 109662306a36Sopenharmony_ci .int_vref_mv = 4096, 109762306a36Sopenharmony_ci .mode_list = max1236_mode_list, 109862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1236_mode_list), 109962306a36Sopenharmony_ci .default_mode = s0to3, 110062306a36Sopenharmony_ci .info = &max1238_info, 110162306a36Sopenharmony_ci .channels = max1036_channels, 110262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1036_channels), 110362306a36Sopenharmony_ci }, 110462306a36Sopenharmony_ci [max1037] = { 110562306a36Sopenharmony_ci .bits = 8, 110662306a36Sopenharmony_ci .int_vref_mv = 2048, 110762306a36Sopenharmony_ci .mode_list = max1236_mode_list, 110862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1236_mode_list), 110962306a36Sopenharmony_ci .default_mode = s0to3, 111062306a36Sopenharmony_ci .info = &max1238_info, 111162306a36Sopenharmony_ci .channels = max1036_channels, 111262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1036_channels), 111362306a36Sopenharmony_ci }, 111462306a36Sopenharmony_ci [max1038] = { 111562306a36Sopenharmony_ci .bits = 8, 111662306a36Sopenharmony_ci .int_vref_mv = 4096, 111762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 111862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 111962306a36Sopenharmony_ci .default_mode = s0to11, 112062306a36Sopenharmony_ci .info = &max1238_info, 112162306a36Sopenharmony_ci .channels = max1038_channels, 112262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1038_channels), 112362306a36Sopenharmony_ci }, 112462306a36Sopenharmony_ci [max1039] = { 112562306a36Sopenharmony_ci .bits = 8, 112662306a36Sopenharmony_ci .int_vref_mv = 2048, 112762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 112862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 112962306a36Sopenharmony_ci .default_mode = s0to11, 113062306a36Sopenharmony_ci .info = &max1238_info, 113162306a36Sopenharmony_ci .channels = max1038_channels, 113262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1038_channels), 113362306a36Sopenharmony_ci }, 113462306a36Sopenharmony_ci [max1136] = { 113562306a36Sopenharmony_ci .bits = 10, 113662306a36Sopenharmony_ci .int_vref_mv = 4096, 113762306a36Sopenharmony_ci .mode_list = max1236_mode_list, 113862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1236_mode_list), 113962306a36Sopenharmony_ci .default_mode = s0to3, 114062306a36Sopenharmony_ci .info = &max1238_info, 114162306a36Sopenharmony_ci .channels = max1136_channels, 114262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1136_channels), 114362306a36Sopenharmony_ci }, 114462306a36Sopenharmony_ci [max1137] = { 114562306a36Sopenharmony_ci .bits = 10, 114662306a36Sopenharmony_ci .int_vref_mv = 2048, 114762306a36Sopenharmony_ci .mode_list = max1236_mode_list, 114862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1236_mode_list), 114962306a36Sopenharmony_ci .default_mode = s0to3, 115062306a36Sopenharmony_ci .info = &max1238_info, 115162306a36Sopenharmony_ci .channels = max1136_channels, 115262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1136_channels), 115362306a36Sopenharmony_ci }, 115462306a36Sopenharmony_ci [max1138] = { 115562306a36Sopenharmony_ci .bits = 10, 115662306a36Sopenharmony_ci .int_vref_mv = 4096, 115762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 115862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 115962306a36Sopenharmony_ci .default_mode = s0to11, 116062306a36Sopenharmony_ci .info = &max1238_info, 116162306a36Sopenharmony_ci .channels = max1138_channels, 116262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1138_channels), 116362306a36Sopenharmony_ci }, 116462306a36Sopenharmony_ci [max1139] = { 116562306a36Sopenharmony_ci .bits = 10, 116662306a36Sopenharmony_ci .int_vref_mv = 2048, 116762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 116862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 116962306a36Sopenharmony_ci .default_mode = s0to11, 117062306a36Sopenharmony_ci .info = &max1238_info, 117162306a36Sopenharmony_ci .channels = max1138_channels, 117262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1138_channels), 117362306a36Sopenharmony_ci }, 117462306a36Sopenharmony_ci [max1236] = { 117562306a36Sopenharmony_ci .bits = 12, 117662306a36Sopenharmony_ci .int_vref_mv = 4096, 117762306a36Sopenharmony_ci .mode_list = max1236_mode_list, 117862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1236_mode_list), 117962306a36Sopenharmony_ci .default_mode = s0to3, 118062306a36Sopenharmony_ci .info = &max1238_info, 118162306a36Sopenharmony_ci .channels = max1236_channels, 118262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1236_channels), 118362306a36Sopenharmony_ci }, 118462306a36Sopenharmony_ci [max1237] = { 118562306a36Sopenharmony_ci .bits = 12, 118662306a36Sopenharmony_ci .int_vref_mv = 2048, 118762306a36Sopenharmony_ci .mode_list = max1236_mode_list, 118862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1236_mode_list), 118962306a36Sopenharmony_ci .default_mode = s0to3, 119062306a36Sopenharmony_ci .info = &max1238_info, 119162306a36Sopenharmony_ci .channels = max1236_channels, 119262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1236_channels), 119362306a36Sopenharmony_ci }, 119462306a36Sopenharmony_ci [max1238] = { 119562306a36Sopenharmony_ci .bits = 12, 119662306a36Sopenharmony_ci .int_vref_mv = 4096, 119762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 119862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 119962306a36Sopenharmony_ci .default_mode = s0to11, 120062306a36Sopenharmony_ci .info = &max1238_info, 120162306a36Sopenharmony_ci .channels = max1238_channels, 120262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1238_channels), 120362306a36Sopenharmony_ci }, 120462306a36Sopenharmony_ci [max1239] = { 120562306a36Sopenharmony_ci .bits = 12, 120662306a36Sopenharmony_ci .int_vref_mv = 2048, 120762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 120862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 120962306a36Sopenharmony_ci .default_mode = s0to11, 121062306a36Sopenharmony_ci .info = &max1238_info, 121162306a36Sopenharmony_ci .channels = max1238_channels, 121262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1238_channels), 121362306a36Sopenharmony_ci }, 121462306a36Sopenharmony_ci [max11600] = { 121562306a36Sopenharmony_ci .bits = 8, 121662306a36Sopenharmony_ci .int_vref_mv = 4096, 121762306a36Sopenharmony_ci .mode_list = max11607_mode_list, 121862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11607_mode_list), 121962306a36Sopenharmony_ci .default_mode = s0to3, 122062306a36Sopenharmony_ci .info = &max1238_info, 122162306a36Sopenharmony_ci .channels = max1036_channels, 122262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1036_channels), 122362306a36Sopenharmony_ci }, 122462306a36Sopenharmony_ci [max11601] = { 122562306a36Sopenharmony_ci .bits = 8, 122662306a36Sopenharmony_ci .int_vref_mv = 2048, 122762306a36Sopenharmony_ci .mode_list = max11607_mode_list, 122862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11607_mode_list), 122962306a36Sopenharmony_ci .default_mode = s0to3, 123062306a36Sopenharmony_ci .info = &max1238_info, 123162306a36Sopenharmony_ci .channels = max1036_channels, 123262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1036_channels), 123362306a36Sopenharmony_ci }, 123462306a36Sopenharmony_ci [max11602] = { 123562306a36Sopenharmony_ci .bits = 8, 123662306a36Sopenharmony_ci .int_vref_mv = 4096, 123762306a36Sopenharmony_ci .mode_list = max11608_mode_list, 123862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11608_mode_list), 123962306a36Sopenharmony_ci .default_mode = s0to7, 124062306a36Sopenharmony_ci .info = &max1238_info, 124162306a36Sopenharmony_ci .channels = max11602_channels, 124262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11602_channels), 124362306a36Sopenharmony_ci }, 124462306a36Sopenharmony_ci [max11603] = { 124562306a36Sopenharmony_ci .bits = 8, 124662306a36Sopenharmony_ci .int_vref_mv = 2048, 124762306a36Sopenharmony_ci .mode_list = max11608_mode_list, 124862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11608_mode_list), 124962306a36Sopenharmony_ci .default_mode = s0to7, 125062306a36Sopenharmony_ci .info = &max1238_info, 125162306a36Sopenharmony_ci .channels = max11602_channels, 125262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11602_channels), 125362306a36Sopenharmony_ci }, 125462306a36Sopenharmony_ci [max11604] = { 125562306a36Sopenharmony_ci .bits = 8, 125662306a36Sopenharmony_ci .int_vref_mv = 4096, 125762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 125862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 125962306a36Sopenharmony_ci .default_mode = s0to11, 126062306a36Sopenharmony_ci .info = &max1238_info, 126162306a36Sopenharmony_ci .channels = max1038_channels, 126262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1038_channels), 126362306a36Sopenharmony_ci }, 126462306a36Sopenharmony_ci [max11605] = { 126562306a36Sopenharmony_ci .bits = 8, 126662306a36Sopenharmony_ci .int_vref_mv = 2048, 126762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 126862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 126962306a36Sopenharmony_ci .default_mode = s0to11, 127062306a36Sopenharmony_ci .info = &max1238_info, 127162306a36Sopenharmony_ci .channels = max1038_channels, 127262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1038_channels), 127362306a36Sopenharmony_ci }, 127462306a36Sopenharmony_ci [max11606] = { 127562306a36Sopenharmony_ci .bits = 10, 127662306a36Sopenharmony_ci .int_vref_mv = 4096, 127762306a36Sopenharmony_ci .mode_list = max11607_mode_list, 127862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11607_mode_list), 127962306a36Sopenharmony_ci .default_mode = s0to3, 128062306a36Sopenharmony_ci .info = &max1238_info, 128162306a36Sopenharmony_ci .channels = max1136_channels, 128262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1136_channels), 128362306a36Sopenharmony_ci }, 128462306a36Sopenharmony_ci [max11607] = { 128562306a36Sopenharmony_ci .bits = 10, 128662306a36Sopenharmony_ci .int_vref_mv = 2048, 128762306a36Sopenharmony_ci .mode_list = max11607_mode_list, 128862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11607_mode_list), 128962306a36Sopenharmony_ci .default_mode = s0to3, 129062306a36Sopenharmony_ci .info = &max1238_info, 129162306a36Sopenharmony_ci .channels = max1136_channels, 129262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1136_channels), 129362306a36Sopenharmony_ci }, 129462306a36Sopenharmony_ci [max11608] = { 129562306a36Sopenharmony_ci .bits = 10, 129662306a36Sopenharmony_ci .int_vref_mv = 4096, 129762306a36Sopenharmony_ci .mode_list = max11608_mode_list, 129862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11608_mode_list), 129962306a36Sopenharmony_ci .default_mode = s0to7, 130062306a36Sopenharmony_ci .info = &max1238_info, 130162306a36Sopenharmony_ci .channels = max11608_channels, 130262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11608_channels), 130362306a36Sopenharmony_ci }, 130462306a36Sopenharmony_ci [max11609] = { 130562306a36Sopenharmony_ci .bits = 10, 130662306a36Sopenharmony_ci .int_vref_mv = 2048, 130762306a36Sopenharmony_ci .mode_list = max11608_mode_list, 130862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11608_mode_list), 130962306a36Sopenharmony_ci .default_mode = s0to7, 131062306a36Sopenharmony_ci .info = &max1238_info, 131162306a36Sopenharmony_ci .channels = max11608_channels, 131262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11608_channels), 131362306a36Sopenharmony_ci }, 131462306a36Sopenharmony_ci [max11610] = { 131562306a36Sopenharmony_ci .bits = 10, 131662306a36Sopenharmony_ci .int_vref_mv = 4096, 131762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 131862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 131962306a36Sopenharmony_ci .default_mode = s0to11, 132062306a36Sopenharmony_ci .info = &max1238_info, 132162306a36Sopenharmony_ci .channels = max1138_channels, 132262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1138_channels), 132362306a36Sopenharmony_ci }, 132462306a36Sopenharmony_ci [max11611] = { 132562306a36Sopenharmony_ci .bits = 10, 132662306a36Sopenharmony_ci .int_vref_mv = 2048, 132762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 132862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 132962306a36Sopenharmony_ci .default_mode = s0to11, 133062306a36Sopenharmony_ci .info = &max1238_info, 133162306a36Sopenharmony_ci .channels = max1138_channels, 133262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1138_channels), 133362306a36Sopenharmony_ci }, 133462306a36Sopenharmony_ci [max11612] = { 133562306a36Sopenharmony_ci .bits = 12, 133662306a36Sopenharmony_ci .int_vref_mv = 4096, 133762306a36Sopenharmony_ci .mode_list = max11607_mode_list, 133862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11607_mode_list), 133962306a36Sopenharmony_ci .default_mode = s0to3, 134062306a36Sopenharmony_ci .info = &max1238_info, 134162306a36Sopenharmony_ci .channels = max1363_channels, 134262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1363_channels), 134362306a36Sopenharmony_ci }, 134462306a36Sopenharmony_ci [max11613] = { 134562306a36Sopenharmony_ci .bits = 12, 134662306a36Sopenharmony_ci .int_vref_mv = 2048, 134762306a36Sopenharmony_ci .mode_list = max11607_mode_list, 134862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11607_mode_list), 134962306a36Sopenharmony_ci .default_mode = s0to3, 135062306a36Sopenharmony_ci .info = &max1238_info, 135162306a36Sopenharmony_ci .channels = max1363_channels, 135262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1363_channels), 135362306a36Sopenharmony_ci }, 135462306a36Sopenharmony_ci [max11614] = { 135562306a36Sopenharmony_ci .bits = 12, 135662306a36Sopenharmony_ci .int_vref_mv = 4096, 135762306a36Sopenharmony_ci .mode_list = max11608_mode_list, 135862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11608_mode_list), 135962306a36Sopenharmony_ci .default_mode = s0to7, 136062306a36Sopenharmony_ci .info = &max1238_info, 136162306a36Sopenharmony_ci .channels = max11614_channels, 136262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11614_channels), 136362306a36Sopenharmony_ci }, 136462306a36Sopenharmony_ci [max11615] = { 136562306a36Sopenharmony_ci .bits = 12, 136662306a36Sopenharmony_ci .int_vref_mv = 2048, 136762306a36Sopenharmony_ci .mode_list = max11608_mode_list, 136862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11608_mode_list), 136962306a36Sopenharmony_ci .default_mode = s0to7, 137062306a36Sopenharmony_ci .info = &max1238_info, 137162306a36Sopenharmony_ci .channels = max11614_channels, 137262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11614_channels), 137362306a36Sopenharmony_ci }, 137462306a36Sopenharmony_ci [max11616] = { 137562306a36Sopenharmony_ci .bits = 12, 137662306a36Sopenharmony_ci .int_vref_mv = 4096, 137762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 137862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 137962306a36Sopenharmony_ci .default_mode = s0to11, 138062306a36Sopenharmony_ci .info = &max1238_info, 138162306a36Sopenharmony_ci .channels = max1238_channels, 138262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1238_channels), 138362306a36Sopenharmony_ci }, 138462306a36Sopenharmony_ci [max11617] = { 138562306a36Sopenharmony_ci .bits = 12, 138662306a36Sopenharmony_ci .int_vref_mv = 2048, 138762306a36Sopenharmony_ci .mode_list = max1238_mode_list, 138862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max1238_mode_list), 138962306a36Sopenharmony_ci .default_mode = s0to11, 139062306a36Sopenharmony_ci .info = &max1238_info, 139162306a36Sopenharmony_ci .channels = max1238_channels, 139262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max1238_channels), 139362306a36Sopenharmony_ci }, 139462306a36Sopenharmony_ci [max11644] = { 139562306a36Sopenharmony_ci .bits = 12, 139662306a36Sopenharmony_ci .int_vref_mv = 4096, 139762306a36Sopenharmony_ci .mode_list = max11644_mode_list, 139862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11644_mode_list), 139962306a36Sopenharmony_ci .default_mode = s0to1, 140062306a36Sopenharmony_ci .info = &max1238_info, 140162306a36Sopenharmony_ci .channels = max11644_channels, 140262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11644_channels), 140362306a36Sopenharmony_ci }, 140462306a36Sopenharmony_ci [max11645] = { 140562306a36Sopenharmony_ci .bits = 12, 140662306a36Sopenharmony_ci .int_vref_mv = 2048, 140762306a36Sopenharmony_ci .mode_list = max11644_mode_list, 140862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11644_mode_list), 140962306a36Sopenharmony_ci .default_mode = s0to1, 141062306a36Sopenharmony_ci .info = &max1238_info, 141162306a36Sopenharmony_ci .channels = max11644_channels, 141262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11644_channels), 141362306a36Sopenharmony_ci }, 141462306a36Sopenharmony_ci [max11646] = { 141562306a36Sopenharmony_ci .bits = 10, 141662306a36Sopenharmony_ci .int_vref_mv = 4096, 141762306a36Sopenharmony_ci .mode_list = max11644_mode_list, 141862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11644_mode_list), 141962306a36Sopenharmony_ci .default_mode = s0to1, 142062306a36Sopenharmony_ci .info = &max1238_info, 142162306a36Sopenharmony_ci .channels = max11646_channels, 142262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11646_channels), 142362306a36Sopenharmony_ci }, 142462306a36Sopenharmony_ci [max11647] = { 142562306a36Sopenharmony_ci .bits = 10, 142662306a36Sopenharmony_ci .int_vref_mv = 2048, 142762306a36Sopenharmony_ci .mode_list = max11644_mode_list, 142862306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(max11644_mode_list), 142962306a36Sopenharmony_ci .default_mode = s0to1, 143062306a36Sopenharmony_ci .info = &max1238_info, 143162306a36Sopenharmony_ci .channels = max11646_channels, 143262306a36Sopenharmony_ci .num_channels = ARRAY_SIZE(max11646_channels), 143362306a36Sopenharmony_ci }, 143462306a36Sopenharmony_ci}; 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_cistatic int max1363_initial_setup(struct max1363_state *st) 143762306a36Sopenharmony_ci{ 143862306a36Sopenharmony_ci st->setupbyte = MAX1363_SETUP_INT_CLOCK 143962306a36Sopenharmony_ci | MAX1363_SETUP_UNIPOLAR 144062306a36Sopenharmony_ci | MAX1363_SETUP_NORESET; 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci if (st->vref) 144362306a36Sopenharmony_ci st->setupbyte |= MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF; 144462306a36Sopenharmony_ci else 144562306a36Sopenharmony_ci st->setupbyte |= MAX1363_SETUP_POWER_UP_INT_REF 144662306a36Sopenharmony_ci | MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT; 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci /* Set scan mode writes the config anyway so wait until then */ 144962306a36Sopenharmony_ci st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte); 145062306a36Sopenharmony_ci st->current_mode = &max1363_mode_table[st->chip_info->default_mode]; 145162306a36Sopenharmony_ci st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte); 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci return max1363_set_scan_mode(st); 145462306a36Sopenharmony_ci} 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_cistatic int max1363_alloc_scan_masks(struct iio_dev *indio_dev) 145762306a36Sopenharmony_ci{ 145862306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 145962306a36Sopenharmony_ci unsigned long *masks; 146062306a36Sopenharmony_ci int i; 146162306a36Sopenharmony_ci 146262306a36Sopenharmony_ci masks = devm_kzalloc(&indio_dev->dev, 146362306a36Sopenharmony_ci array3_size(BITS_TO_LONGS(MAX1363_MAX_CHANNELS), 146462306a36Sopenharmony_ci sizeof(long), 146562306a36Sopenharmony_ci st->chip_info->num_modes + 1), 146662306a36Sopenharmony_ci GFP_KERNEL); 146762306a36Sopenharmony_ci if (!masks) 146862306a36Sopenharmony_ci return -ENOMEM; 146962306a36Sopenharmony_ci 147062306a36Sopenharmony_ci for (i = 0; i < st->chip_info->num_modes; i++) 147162306a36Sopenharmony_ci bitmap_copy(masks + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i, 147262306a36Sopenharmony_ci max1363_mode_table[st->chip_info->mode_list[i]] 147362306a36Sopenharmony_ci .modemask, MAX1363_MAX_CHANNELS); 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci indio_dev->available_scan_masks = masks; 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci return 0; 147862306a36Sopenharmony_ci} 147962306a36Sopenharmony_ci 148062306a36Sopenharmony_cistatic irqreturn_t max1363_trigger_handler(int irq, void *p) 148162306a36Sopenharmony_ci{ 148262306a36Sopenharmony_ci struct iio_poll_func *pf = p; 148362306a36Sopenharmony_ci struct iio_dev *indio_dev = pf->indio_dev; 148462306a36Sopenharmony_ci struct max1363_state *st = iio_priv(indio_dev); 148562306a36Sopenharmony_ci __u8 *rxbuf; 148662306a36Sopenharmony_ci int b_sent; 148762306a36Sopenharmony_ci size_t d_size; 148862306a36Sopenharmony_ci unsigned long numvals = bitmap_weight(st->current_mode->modemask, 148962306a36Sopenharmony_ci MAX1363_MAX_CHANNELS); 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_ci /* Ensure the timestamp is 8 byte aligned */ 149262306a36Sopenharmony_ci if (st->chip_info->bits != 8) 149362306a36Sopenharmony_ci d_size = numvals*2; 149462306a36Sopenharmony_ci else 149562306a36Sopenharmony_ci d_size = numvals; 149662306a36Sopenharmony_ci if (indio_dev->scan_timestamp) { 149762306a36Sopenharmony_ci d_size += sizeof(s64); 149862306a36Sopenharmony_ci if (d_size % sizeof(s64)) 149962306a36Sopenharmony_ci d_size += sizeof(s64) - (d_size % sizeof(s64)); 150062306a36Sopenharmony_ci } 150162306a36Sopenharmony_ci /* Monitor mode prevents reading. Whilst not currently implemented 150262306a36Sopenharmony_ci * might as well have this test in here in the meantime as it does 150362306a36Sopenharmony_ci * no harm. 150462306a36Sopenharmony_ci */ 150562306a36Sopenharmony_ci if (numvals == 0) 150662306a36Sopenharmony_ci goto done; 150762306a36Sopenharmony_ci 150862306a36Sopenharmony_ci rxbuf = kmalloc(d_size, GFP_KERNEL); 150962306a36Sopenharmony_ci if (rxbuf == NULL) 151062306a36Sopenharmony_ci goto done; 151162306a36Sopenharmony_ci if (st->chip_info->bits != 8) 151262306a36Sopenharmony_ci b_sent = st->recv(st->client, rxbuf, numvals * 2); 151362306a36Sopenharmony_ci else 151462306a36Sopenharmony_ci b_sent = st->recv(st->client, rxbuf, numvals); 151562306a36Sopenharmony_ci if (b_sent < 0) 151662306a36Sopenharmony_ci goto done_free; 151762306a36Sopenharmony_ci 151862306a36Sopenharmony_ci iio_push_to_buffers_with_timestamp(indio_dev, rxbuf, 151962306a36Sopenharmony_ci iio_get_time_ns(indio_dev)); 152062306a36Sopenharmony_ci 152162306a36Sopenharmony_cidone_free: 152262306a36Sopenharmony_ci kfree(rxbuf); 152362306a36Sopenharmony_cidone: 152462306a36Sopenharmony_ci iio_trigger_notify_done(indio_dev->trig); 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci return IRQ_HANDLED; 152762306a36Sopenharmony_ci} 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci#define MAX1363_COMPATIBLE(of_compatible, cfg) { \ 153062306a36Sopenharmony_ci .compatible = of_compatible, \ 153162306a36Sopenharmony_ci .data = &max1363_chip_info_tbl[cfg], \ 153262306a36Sopenharmony_ci} 153362306a36Sopenharmony_ci 153462306a36Sopenharmony_cistatic const struct of_device_id max1363_of_match[] = { 153562306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1361", max1361), 153662306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1362", max1362), 153762306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1363", max1363), 153862306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1364", max1364), 153962306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1036", max1036), 154062306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1037", max1037), 154162306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1038", max1038), 154262306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1039", max1039), 154362306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1136", max1136), 154462306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1137", max1137), 154562306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1138", max1138), 154662306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1139", max1139), 154762306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1236", max1236), 154862306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1237", max1237), 154962306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1238", max1238), 155062306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max1239", max1239), 155162306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11600", max11600), 155262306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11601", max11601), 155362306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11602", max11602), 155462306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11603", max11603), 155562306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11604", max11604), 155662306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11605", max11605), 155762306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11606", max11606), 155862306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11607", max11607), 155962306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11608", max11608), 156062306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11609", max11609), 156162306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11610", max11610), 156262306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11611", max11611), 156362306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11612", max11612), 156462306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11613", max11613), 156562306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11614", max11614), 156662306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11615", max11615), 156762306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11616", max11616), 156862306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11617", max11617), 156962306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11644", max11644), 157062306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11645", max11645), 157162306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11646", max11646), 157262306a36Sopenharmony_ci MAX1363_COMPATIBLE("maxim,max11647", max11647), 157362306a36Sopenharmony_ci { /* sentinel */ } 157462306a36Sopenharmony_ci}; 157562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, max1363_of_match); 157662306a36Sopenharmony_ci 157762306a36Sopenharmony_cistatic void max1363_reg_disable(void *reg) 157862306a36Sopenharmony_ci{ 157962306a36Sopenharmony_ci regulator_disable(reg); 158062306a36Sopenharmony_ci} 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_cistatic int max1363_probe(struct i2c_client *client) 158362306a36Sopenharmony_ci{ 158462306a36Sopenharmony_ci const struct i2c_device_id *id = i2c_client_get_device_id(client); 158562306a36Sopenharmony_ci int ret; 158662306a36Sopenharmony_ci struct max1363_state *st; 158762306a36Sopenharmony_ci struct iio_dev *indio_dev; 158862306a36Sopenharmony_ci struct regulator *vref; 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci indio_dev = devm_iio_device_alloc(&client->dev, 159162306a36Sopenharmony_ci sizeof(struct max1363_state)); 159262306a36Sopenharmony_ci if (!indio_dev) 159362306a36Sopenharmony_ci return -ENOMEM; 159462306a36Sopenharmony_ci 159562306a36Sopenharmony_ci st = iio_priv(indio_dev); 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci mutex_init(&st->lock); 159862306a36Sopenharmony_ci ret = devm_regulator_get_enable(&client->dev, "vcc"); 159962306a36Sopenharmony_ci if (ret) 160062306a36Sopenharmony_ci return ret; 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci st->chip_info = device_get_match_data(&client->dev); 160362306a36Sopenharmony_ci if (!st->chip_info) 160462306a36Sopenharmony_ci st->chip_info = &max1363_chip_info_tbl[id->driver_data]; 160562306a36Sopenharmony_ci st->client = client; 160662306a36Sopenharmony_ci 160762306a36Sopenharmony_ci st->vref_uv = st->chip_info->int_vref_mv * 1000; 160862306a36Sopenharmony_ci vref = devm_regulator_get_optional(&client->dev, "vref"); 160962306a36Sopenharmony_ci if (!IS_ERR(vref)) { 161062306a36Sopenharmony_ci int vref_uv; 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci ret = regulator_enable(vref); 161362306a36Sopenharmony_ci if (ret) 161462306a36Sopenharmony_ci return ret; 161562306a36Sopenharmony_ci 161662306a36Sopenharmony_ci ret = devm_add_action_or_reset(&client->dev, max1363_reg_disable, vref); 161762306a36Sopenharmony_ci if (ret) 161862306a36Sopenharmony_ci return ret; 161962306a36Sopenharmony_ci 162062306a36Sopenharmony_ci st->vref = vref; 162162306a36Sopenharmony_ci vref_uv = regulator_get_voltage(vref); 162262306a36Sopenharmony_ci if (vref_uv <= 0) 162362306a36Sopenharmony_ci return -EINVAL; 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_ci st->vref_uv = vref_uv; 162662306a36Sopenharmony_ci } 162762306a36Sopenharmony_ci 162862306a36Sopenharmony_ci if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 162962306a36Sopenharmony_ci st->send = i2c_master_send; 163062306a36Sopenharmony_ci st->recv = i2c_master_recv; 163162306a36Sopenharmony_ci } else if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE) 163262306a36Sopenharmony_ci && st->chip_info->bits == 8) { 163362306a36Sopenharmony_ci st->send = max1363_smbus_send; 163462306a36Sopenharmony_ci st->recv = max1363_smbus_recv; 163562306a36Sopenharmony_ci } else { 163662306a36Sopenharmony_ci return -EOPNOTSUPP; 163762306a36Sopenharmony_ci } 163862306a36Sopenharmony_ci 163962306a36Sopenharmony_ci ret = max1363_alloc_scan_masks(indio_dev); 164062306a36Sopenharmony_ci if (ret) 164162306a36Sopenharmony_ci return ret; 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci indio_dev->name = id->name; 164462306a36Sopenharmony_ci indio_dev->channels = st->chip_info->channels; 164562306a36Sopenharmony_ci indio_dev->num_channels = st->chip_info->num_channels; 164662306a36Sopenharmony_ci indio_dev->info = st->chip_info->info; 164762306a36Sopenharmony_ci indio_dev->modes = INDIO_DIRECT_MODE; 164862306a36Sopenharmony_ci ret = max1363_initial_setup(st); 164962306a36Sopenharmony_ci if (ret < 0) 165062306a36Sopenharmony_ci return ret; 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_ci ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL, 165362306a36Sopenharmony_ci &max1363_trigger_handler, NULL); 165462306a36Sopenharmony_ci if (ret) 165562306a36Sopenharmony_ci return ret; 165662306a36Sopenharmony_ci 165762306a36Sopenharmony_ci if (client->irq) { 165862306a36Sopenharmony_ci ret = devm_request_threaded_irq(&client->dev, st->client->irq, 165962306a36Sopenharmony_ci NULL, 166062306a36Sopenharmony_ci &max1363_event_handler, 166162306a36Sopenharmony_ci IRQF_TRIGGER_RISING | IRQF_ONESHOT, 166262306a36Sopenharmony_ci "max1363_event", 166362306a36Sopenharmony_ci indio_dev); 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_ci if (ret) 166662306a36Sopenharmony_ci return ret; 166762306a36Sopenharmony_ci } 166862306a36Sopenharmony_ci 166962306a36Sopenharmony_ci return devm_iio_device_register(&client->dev, indio_dev); 167062306a36Sopenharmony_ci} 167162306a36Sopenharmony_ci 167262306a36Sopenharmony_cistatic const struct i2c_device_id max1363_id[] = { 167362306a36Sopenharmony_ci { "max1361", max1361 }, 167462306a36Sopenharmony_ci { "max1362", max1362 }, 167562306a36Sopenharmony_ci { "max1363", max1363 }, 167662306a36Sopenharmony_ci { "max1364", max1364 }, 167762306a36Sopenharmony_ci { "max1036", max1036 }, 167862306a36Sopenharmony_ci { "max1037", max1037 }, 167962306a36Sopenharmony_ci { "max1038", max1038 }, 168062306a36Sopenharmony_ci { "max1039", max1039 }, 168162306a36Sopenharmony_ci { "max1136", max1136 }, 168262306a36Sopenharmony_ci { "max1137", max1137 }, 168362306a36Sopenharmony_ci { "max1138", max1138 }, 168462306a36Sopenharmony_ci { "max1139", max1139 }, 168562306a36Sopenharmony_ci { "max1236", max1236 }, 168662306a36Sopenharmony_ci { "max1237", max1237 }, 168762306a36Sopenharmony_ci { "max1238", max1238 }, 168862306a36Sopenharmony_ci { "max1239", max1239 }, 168962306a36Sopenharmony_ci { "max11600", max11600 }, 169062306a36Sopenharmony_ci { "max11601", max11601 }, 169162306a36Sopenharmony_ci { "max11602", max11602 }, 169262306a36Sopenharmony_ci { "max11603", max11603 }, 169362306a36Sopenharmony_ci { "max11604", max11604 }, 169462306a36Sopenharmony_ci { "max11605", max11605 }, 169562306a36Sopenharmony_ci { "max11606", max11606 }, 169662306a36Sopenharmony_ci { "max11607", max11607 }, 169762306a36Sopenharmony_ci { "max11608", max11608 }, 169862306a36Sopenharmony_ci { "max11609", max11609 }, 169962306a36Sopenharmony_ci { "max11610", max11610 }, 170062306a36Sopenharmony_ci { "max11611", max11611 }, 170162306a36Sopenharmony_ci { "max11612", max11612 }, 170262306a36Sopenharmony_ci { "max11613", max11613 }, 170362306a36Sopenharmony_ci { "max11614", max11614 }, 170462306a36Sopenharmony_ci { "max11615", max11615 }, 170562306a36Sopenharmony_ci { "max11616", max11616 }, 170662306a36Sopenharmony_ci { "max11617", max11617 }, 170762306a36Sopenharmony_ci { "max11644", max11644 }, 170862306a36Sopenharmony_ci { "max11645", max11645 }, 170962306a36Sopenharmony_ci { "max11646", max11646 }, 171062306a36Sopenharmony_ci { "max11647", max11647 }, 171162306a36Sopenharmony_ci {} 171262306a36Sopenharmony_ci}; 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, max1363_id); 171562306a36Sopenharmony_ci 171662306a36Sopenharmony_cistatic struct i2c_driver max1363_driver = { 171762306a36Sopenharmony_ci .driver = { 171862306a36Sopenharmony_ci .name = "max1363", 171962306a36Sopenharmony_ci .of_match_table = max1363_of_match, 172062306a36Sopenharmony_ci }, 172162306a36Sopenharmony_ci .probe = max1363_probe, 172262306a36Sopenharmony_ci .id_table = max1363_id, 172362306a36Sopenharmony_ci}; 172462306a36Sopenharmony_cimodule_i2c_driver(max1363_driver); 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ciMODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>"); 172762306a36Sopenharmony_ciMODULE_DESCRIPTION("Maxim 1363 ADC"); 172862306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 1729