ina238.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Driver for Texas Instruments INA238 power monitor chip
  4. * Datasheet: https://www.ti.com/product/ina238
  5. *
  6. * Copyright (C) 2021 Nathan Rossi <[email protected]>
  7. */
  8. #include <linux/err.h>
  9. #include <linux/hwmon.h>
  10. #include <linux/i2c.h>
  11. #include <linux/init.h>
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/of.h>
  15. #include <linux/regmap.h>
  16. #include <linux/platform_data/ina2xx.h>
  17. /* INA238 register definitions */
  18. #define INA238_CONFIG 0x0
  19. #define INA238_ADC_CONFIG 0x1
  20. #define INA238_SHUNT_CALIBRATION 0x2
  21. #define INA238_SHUNT_VOLTAGE 0x4
  22. #define INA238_BUS_VOLTAGE 0x5
  23. #define INA238_DIE_TEMP 0x6
  24. #define INA238_CURRENT 0x7
  25. #define INA238_POWER 0x8
  26. #define INA238_DIAG_ALERT 0xb
  27. #define INA238_SHUNT_OVER_VOLTAGE 0xc
  28. #define INA238_SHUNT_UNDER_VOLTAGE 0xd
  29. #define INA238_BUS_OVER_VOLTAGE 0xe
  30. #define INA238_BUS_UNDER_VOLTAGE 0xf
  31. #define INA238_TEMP_LIMIT 0x10
  32. #define INA238_POWER_LIMIT 0x11
  33. #define INA238_DEVICE_ID 0x3f
  34. #define INA238_CONFIG_ADCRANGE BIT(4)
  35. #define INA238_DIAG_ALERT_TMPOL BIT(7)
  36. #define INA238_DIAG_ALERT_SHNTOL BIT(6)
  37. #define INA238_DIAG_ALERT_SHNTUL BIT(5)
  38. #define INA238_DIAG_ALERT_BUSOL BIT(4)
  39. #define INA238_DIAG_ALERT_BUSUL BIT(3)
  40. #define INA238_DIAG_ALERT_POL BIT(2)
  41. #define INA238_REGISTERS 0x11
  42. #define INA238_RSHUNT_DEFAULT 10000 /* uOhm */
  43. /* Default configuration of device on reset. */
  44. #define INA238_CONFIG_DEFAULT 0
  45. /* 16 sample averaging, 1052us conversion time, continuous mode */
  46. #define INA238_ADC_CONFIG_DEFAULT 0xfb6a
  47. /* Configure alerts to be based on averaged value (SLOWALERT) */
  48. #define INA238_DIAG_ALERT_DEFAULT 0x2000
  49. /*
  50. * This driver uses a fixed calibration value in order to scale current/power
  51. * based on a fixed shunt resistor value. This allows for conversion within the
  52. * device to avoid integer limits whilst current/power accuracy is scaled
  53. * relative to the shunt resistor value within the driver. This is similar to
  54. * how the ina2xx driver handles current/power scaling.
  55. *
  56. * The end result of this is that increasing shunt values (from a fixed 20 mOhm
  57. * shunt) increase the effective current/power accuracy whilst limiting the
  58. * range and decreasing shunt values decrease the effective accuracy but
  59. * increase the range.
  60. *
  61. * The value of the Current register is calculated given the following:
  62. * Current (A) = (shunt voltage register * 5) * calibration / 81920
  63. *
  64. * The maximum shunt voltage is 163.835 mV (0x7fff, ADC_RANGE = 0, gain = 4).
  65. * With the maximum current value of 0x7fff and a fixed shunt value results in
  66. * a calibration value of 16384 (0x4000).
  67. *
  68. * 0x7fff = (0x7fff * 5) * calibration / 81920
  69. * calibration = 0x4000
  70. *
  71. * Equivalent calibration is applied for the Power register (maximum value for
  72. * bus voltage is 102396.875 mV, 0x7fff), where the maximum power that can
  73. * occur is ~16776192 uW (register value 0x147a8):
  74. *
  75. * This scaling means the resulting values for Current and Power registers need
  76. * to be scaled by the difference between the fixed shunt resistor and the
  77. * actual shunt resistor:
  78. *
  79. * shunt = 0x4000 / (819.2 * 10^6) / 0.001 = 20000 uOhms (with 1mA/lsb)
  80. *
  81. * Current (mA) = register value * 20000 / rshunt / 4 * gain
  82. * Power (W) = 0.2 * register value * 20000 / rshunt / 4 * gain
  83. */
  84. #define INA238_CALIBRATION_VALUE 16384
  85. #define INA238_FIXED_SHUNT 20000
  86. #define INA238_SHUNT_VOLTAGE_LSB 5 /* 5 uV/lsb */
  87. #define INA238_BUS_VOLTAGE_LSB 3125 /* 3.125 mV/lsb */
  88. #define INA238_DIE_TEMP_LSB 125 /* 125 mC/lsb */
  89. static struct regmap_config ina238_regmap_config = {
  90. .max_register = INA238_REGISTERS,
  91. .reg_bits = 8,
  92. .val_bits = 16,
  93. };
  94. struct ina238_data {
  95. struct i2c_client *client;
  96. struct mutex config_lock;
  97. struct regmap *regmap;
  98. u32 rshunt;
  99. int gain;
  100. };
  101. static int ina238_read_reg24(const struct i2c_client *client, u8 reg, u32 *val)
  102. {
  103. u8 data[3];
  104. int err;
  105. /* 24-bit register read */
  106. err = i2c_smbus_read_i2c_block_data(client, reg, 3, data);
  107. if (err < 0)
  108. return err;
  109. if (err != 3)
  110. return -EIO;
  111. *val = (data[0] << 16) | (data[1] << 8) | data[2];
  112. return 0;
  113. }
  114. static int ina238_read_in(struct device *dev, u32 attr, int channel,
  115. long *val)
  116. {
  117. struct ina238_data *data = dev_get_drvdata(dev);
  118. int reg, mask;
  119. int regval;
  120. int err;
  121. switch (channel) {
  122. case 0:
  123. switch (attr) {
  124. case hwmon_in_input:
  125. reg = INA238_SHUNT_VOLTAGE;
  126. break;
  127. case hwmon_in_max:
  128. reg = INA238_SHUNT_OVER_VOLTAGE;
  129. break;
  130. case hwmon_in_min:
  131. reg = INA238_SHUNT_UNDER_VOLTAGE;
  132. break;
  133. case hwmon_in_max_alarm:
  134. reg = INA238_DIAG_ALERT;
  135. mask = INA238_DIAG_ALERT_SHNTOL;
  136. break;
  137. case hwmon_in_min_alarm:
  138. reg = INA238_DIAG_ALERT;
  139. mask = INA238_DIAG_ALERT_SHNTUL;
  140. break;
  141. default:
  142. return -EOPNOTSUPP;
  143. }
  144. break;
  145. case 1:
  146. switch (attr) {
  147. case hwmon_in_input:
  148. reg = INA238_BUS_VOLTAGE;
  149. break;
  150. case hwmon_in_max:
  151. reg = INA238_BUS_OVER_VOLTAGE;
  152. break;
  153. case hwmon_in_min:
  154. reg = INA238_BUS_UNDER_VOLTAGE;
  155. break;
  156. case hwmon_in_max_alarm:
  157. reg = INA238_DIAG_ALERT;
  158. mask = INA238_DIAG_ALERT_BUSOL;
  159. break;
  160. case hwmon_in_min_alarm:
  161. reg = INA238_DIAG_ALERT;
  162. mask = INA238_DIAG_ALERT_BUSUL;
  163. break;
  164. default:
  165. return -EOPNOTSUPP;
  166. }
  167. break;
  168. default:
  169. return -EOPNOTSUPP;
  170. }
  171. err = regmap_read(data->regmap, reg, &regval);
  172. if (err < 0)
  173. return err;
  174. switch (attr) {
  175. case hwmon_in_input:
  176. case hwmon_in_max:
  177. case hwmon_in_min:
  178. /* signed register, value in mV */
  179. regval = (s16)regval;
  180. if (channel == 0)
  181. /* gain of 1 -> LSB / 4 */
  182. *val = (regval * INA238_SHUNT_VOLTAGE_LSB) /
  183. (1000 * (4 - data->gain + 1));
  184. else
  185. *val = (regval * INA238_BUS_VOLTAGE_LSB) / 1000;
  186. break;
  187. case hwmon_in_max_alarm:
  188. case hwmon_in_min_alarm:
  189. *val = !!(regval & mask);
  190. break;
  191. }
  192. return 0;
  193. }
  194. static int ina238_write_in(struct device *dev, u32 attr, int channel,
  195. long val)
  196. {
  197. struct ina238_data *data = dev_get_drvdata(dev);
  198. int regval;
  199. if (attr != hwmon_in_max && attr != hwmon_in_min)
  200. return -EOPNOTSUPP;
  201. /* convert decimal to register value */
  202. switch (channel) {
  203. case 0:
  204. /* signed value, clamp to max range +/-163 mV */
  205. regval = clamp_val(val, -163, 163);
  206. regval = (regval * 1000 * (4 - data->gain + 1)) /
  207. INA238_SHUNT_VOLTAGE_LSB;
  208. regval = clamp_val(regval, S16_MIN, S16_MAX);
  209. switch (attr) {
  210. case hwmon_in_max:
  211. return regmap_write(data->regmap,
  212. INA238_SHUNT_OVER_VOLTAGE, regval);
  213. case hwmon_in_min:
  214. return regmap_write(data->regmap,
  215. INA238_SHUNT_UNDER_VOLTAGE, regval);
  216. default:
  217. return -EOPNOTSUPP;
  218. }
  219. case 1:
  220. /* signed value, positive values only. Clamp to max 102.396 V */
  221. regval = clamp_val(val, 0, 102396);
  222. regval = (regval * 1000) / INA238_BUS_VOLTAGE_LSB;
  223. regval = clamp_val(regval, 0, S16_MAX);
  224. switch (attr) {
  225. case hwmon_in_max:
  226. return regmap_write(data->regmap,
  227. INA238_BUS_OVER_VOLTAGE, regval);
  228. case hwmon_in_min:
  229. return regmap_write(data->regmap,
  230. INA238_BUS_UNDER_VOLTAGE, regval);
  231. default:
  232. return -EOPNOTSUPP;
  233. }
  234. default:
  235. return -EOPNOTSUPP;
  236. }
  237. }
  238. static int ina238_read_current(struct device *dev, u32 attr, long *val)
  239. {
  240. struct ina238_data *data = dev_get_drvdata(dev);
  241. int regval;
  242. int err;
  243. switch (attr) {
  244. case hwmon_curr_input:
  245. err = regmap_read(data->regmap, INA238_CURRENT, &regval);
  246. if (err < 0)
  247. return err;
  248. /* Signed register, fixed 1mA current lsb. result in mA */
  249. *val = div_s64((s16)regval * INA238_FIXED_SHUNT * data->gain,
  250. data->rshunt * 4);
  251. break;
  252. default:
  253. return -EOPNOTSUPP;
  254. }
  255. return 0;
  256. }
  257. static int ina238_read_power(struct device *dev, u32 attr, long *val)
  258. {
  259. struct ina238_data *data = dev_get_drvdata(dev);
  260. long long power;
  261. int regval;
  262. int err;
  263. switch (attr) {
  264. case hwmon_power_input:
  265. err = ina238_read_reg24(data->client, INA238_POWER, &regval);
  266. if (err)
  267. return err;
  268. /* Fixed 1mA lsb, scaled by 1000000 to have result in uW */
  269. power = div_u64(regval * 1000ULL * INA238_FIXED_SHUNT *
  270. data->gain, 20 * data->rshunt);
  271. /* Clamp value to maximum value of long */
  272. *val = clamp_val(power, 0, LONG_MAX);
  273. break;
  274. case hwmon_power_max:
  275. err = regmap_read(data->regmap, INA238_POWER_LIMIT, &regval);
  276. if (err)
  277. return err;
  278. /*
  279. * Truncated 24-bit compare register, lower 8-bits are
  280. * truncated. Same conversion to/from uW as POWER register.
  281. */
  282. power = div_u64((regval << 8) * 1000ULL * INA238_FIXED_SHUNT *
  283. data->gain, 20 * data->rshunt);
  284. /* Clamp value to maximum value of long */
  285. *val = clamp_val(power, 0, LONG_MAX);
  286. break;
  287. case hwmon_power_max_alarm:
  288. err = regmap_read(data->regmap, INA238_DIAG_ALERT, &regval);
  289. if (err)
  290. return err;
  291. *val = !!(regval & INA238_DIAG_ALERT_POL);
  292. break;
  293. default:
  294. return -EOPNOTSUPP;
  295. }
  296. return 0;
  297. }
  298. static int ina238_write_power(struct device *dev, u32 attr, long val)
  299. {
  300. struct ina238_data *data = dev_get_drvdata(dev);
  301. long regval;
  302. if (attr != hwmon_power_max)
  303. return -EOPNOTSUPP;
  304. /*
  305. * Unsigned postive values. Compared against the 24-bit power register,
  306. * lower 8-bits are truncated. Same conversion to/from uW as POWER
  307. * register.
  308. */
  309. regval = clamp_val(val, 0, LONG_MAX);
  310. regval = div_u64(val * 20ULL * data->rshunt,
  311. 1000ULL * INA238_FIXED_SHUNT * data->gain);
  312. regval = clamp_val(regval >> 8, 0, U16_MAX);
  313. return regmap_write(data->regmap, INA238_POWER_LIMIT, regval);
  314. }
  315. static int ina238_read_temp(struct device *dev, u32 attr, long *val)
  316. {
  317. struct ina238_data *data = dev_get_drvdata(dev);
  318. int regval;
  319. int err;
  320. switch (attr) {
  321. case hwmon_temp_input:
  322. err = regmap_read(data->regmap, INA238_DIE_TEMP, &regval);
  323. if (err)
  324. return err;
  325. /* Signed, bits 15-4 of register, result in mC */
  326. *val = ((s16)regval >> 4) * INA238_DIE_TEMP_LSB;
  327. break;
  328. case hwmon_temp_max:
  329. err = regmap_read(data->regmap, INA238_TEMP_LIMIT, &regval);
  330. if (err)
  331. return err;
  332. /* Signed, bits 15-4 of register, result in mC */
  333. *val = ((s16)regval >> 4) * INA238_DIE_TEMP_LSB;
  334. break;
  335. case hwmon_temp_max_alarm:
  336. err = regmap_read(data->regmap, INA238_DIAG_ALERT, &regval);
  337. if (err)
  338. return err;
  339. *val = !!(regval & INA238_DIAG_ALERT_TMPOL);
  340. break;
  341. default:
  342. return -EOPNOTSUPP;
  343. }
  344. return 0;
  345. }
  346. static int ina238_write_temp(struct device *dev, u32 attr, long val)
  347. {
  348. struct ina238_data *data = dev_get_drvdata(dev);
  349. int regval;
  350. if (attr != hwmon_temp_max)
  351. return -EOPNOTSUPP;
  352. /* Signed, bits 15-4 of register */
  353. regval = (val / INA238_DIE_TEMP_LSB) << 4;
  354. regval = clamp_val(regval, S16_MIN, S16_MAX) & 0xfff0;
  355. return regmap_write(data->regmap, INA238_TEMP_LIMIT, regval);
  356. }
  357. static int ina238_read(struct device *dev, enum hwmon_sensor_types type,
  358. u32 attr, int channel, long *val)
  359. {
  360. switch (type) {
  361. case hwmon_in:
  362. return ina238_read_in(dev, attr, channel, val);
  363. case hwmon_curr:
  364. return ina238_read_current(dev, attr, val);
  365. case hwmon_power:
  366. return ina238_read_power(dev, attr, val);
  367. case hwmon_temp:
  368. return ina238_read_temp(dev, attr, val);
  369. default:
  370. return -EOPNOTSUPP;
  371. }
  372. return 0;
  373. }
  374. static int ina238_write(struct device *dev, enum hwmon_sensor_types type,
  375. u32 attr, int channel, long val)
  376. {
  377. struct ina238_data *data = dev_get_drvdata(dev);
  378. int err;
  379. mutex_lock(&data->config_lock);
  380. switch (type) {
  381. case hwmon_in:
  382. err = ina238_write_in(dev, attr, channel, val);
  383. break;
  384. case hwmon_power:
  385. err = ina238_write_power(dev, attr, val);
  386. break;
  387. case hwmon_temp:
  388. err = ina238_write_temp(dev, attr, val);
  389. break;
  390. default:
  391. err = -EOPNOTSUPP;
  392. break;
  393. }
  394. mutex_unlock(&data->config_lock);
  395. return err;
  396. }
  397. static umode_t ina238_is_visible(const void *drvdata,
  398. enum hwmon_sensor_types type,
  399. u32 attr, int channel)
  400. {
  401. switch (type) {
  402. case hwmon_in:
  403. switch (attr) {
  404. case hwmon_in_input:
  405. case hwmon_in_max_alarm:
  406. case hwmon_in_min_alarm:
  407. return 0444;
  408. case hwmon_in_max:
  409. case hwmon_in_min:
  410. return 0644;
  411. default:
  412. return 0;
  413. }
  414. case hwmon_curr:
  415. switch (attr) {
  416. case hwmon_curr_input:
  417. return 0444;
  418. default:
  419. return 0;
  420. }
  421. case hwmon_power:
  422. switch (attr) {
  423. case hwmon_power_input:
  424. case hwmon_power_max_alarm:
  425. return 0444;
  426. case hwmon_power_max:
  427. return 0644;
  428. default:
  429. return 0;
  430. }
  431. case hwmon_temp:
  432. switch (attr) {
  433. case hwmon_temp_input:
  434. case hwmon_temp_max_alarm:
  435. return 0444;
  436. case hwmon_temp_max:
  437. return 0644;
  438. default:
  439. return 0;
  440. }
  441. default:
  442. return 0;
  443. }
  444. }
  445. #define INA238_HWMON_IN_CONFIG (HWMON_I_INPUT | \
  446. HWMON_I_MAX | HWMON_I_MAX_ALARM | \
  447. HWMON_I_MIN | HWMON_I_MIN_ALARM)
  448. static const struct hwmon_channel_info *ina238_info[] = {
  449. HWMON_CHANNEL_INFO(in,
  450. /* 0: shunt voltage */
  451. INA238_HWMON_IN_CONFIG,
  452. /* 1: bus voltage */
  453. INA238_HWMON_IN_CONFIG),
  454. HWMON_CHANNEL_INFO(curr,
  455. /* 0: current through shunt */
  456. HWMON_C_INPUT),
  457. HWMON_CHANNEL_INFO(power,
  458. /* 0: power */
  459. HWMON_P_INPUT | HWMON_P_MAX | HWMON_P_MAX_ALARM),
  460. HWMON_CHANNEL_INFO(temp,
  461. /* 0: die temperature */
  462. HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_ALARM),
  463. NULL
  464. };
  465. static const struct hwmon_ops ina238_hwmon_ops = {
  466. .is_visible = ina238_is_visible,
  467. .read = ina238_read,
  468. .write = ina238_write,
  469. };
  470. static const struct hwmon_chip_info ina238_chip_info = {
  471. .ops = &ina238_hwmon_ops,
  472. .info = ina238_info,
  473. };
  474. static int ina238_probe(struct i2c_client *client)
  475. {
  476. struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev);
  477. struct device *dev = &client->dev;
  478. struct device *hwmon_dev;
  479. struct ina238_data *data;
  480. int config;
  481. int ret;
  482. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  483. if (!data)
  484. return -ENOMEM;
  485. data->client = client;
  486. mutex_init(&data->config_lock);
  487. data->regmap = devm_regmap_init_i2c(client, &ina238_regmap_config);
  488. if (IS_ERR(data->regmap)) {
  489. dev_err(dev, "failed to allocate register map\n");
  490. return PTR_ERR(data->regmap);
  491. }
  492. /* load shunt value */
  493. data->rshunt = INA238_RSHUNT_DEFAULT;
  494. if (device_property_read_u32(dev, "shunt-resistor", &data->rshunt) < 0 && pdata)
  495. data->rshunt = pdata->shunt_uohms;
  496. if (data->rshunt == 0) {
  497. dev_err(dev, "invalid shunt resister value %u\n", data->rshunt);
  498. return -EINVAL;
  499. }
  500. /* load shunt gain value */
  501. if (device_property_read_u32(dev, "ti,shunt-gain", &data->gain) < 0)
  502. data->gain = 4; /* Default of ADCRANGE = 0 */
  503. if (data->gain != 1 && data->gain != 4) {
  504. dev_err(dev, "invalid shunt gain value %u\n", data->gain);
  505. return -EINVAL;
  506. }
  507. /* Setup CONFIG register */
  508. config = INA238_CONFIG_DEFAULT;
  509. if (data->gain == 1)
  510. config |= INA238_CONFIG_ADCRANGE; /* ADCRANGE = 1 is /1 */
  511. ret = regmap_write(data->regmap, INA238_CONFIG, config);
  512. if (ret < 0) {
  513. dev_err(dev, "error configuring the device: %d\n", ret);
  514. return -ENODEV;
  515. }
  516. /* Setup ADC_CONFIG register */
  517. ret = regmap_write(data->regmap, INA238_ADC_CONFIG,
  518. INA238_ADC_CONFIG_DEFAULT);
  519. if (ret < 0) {
  520. dev_err(dev, "error configuring the device: %d\n", ret);
  521. return -ENODEV;
  522. }
  523. /* Setup SHUNT_CALIBRATION register with fixed value */
  524. ret = regmap_write(data->regmap, INA238_SHUNT_CALIBRATION,
  525. INA238_CALIBRATION_VALUE);
  526. if (ret < 0) {
  527. dev_err(dev, "error configuring the device: %d\n", ret);
  528. return -ENODEV;
  529. }
  530. /* Setup alert/alarm configuration */
  531. ret = regmap_write(data->regmap, INA238_DIAG_ALERT,
  532. INA238_DIAG_ALERT_DEFAULT);
  533. if (ret < 0) {
  534. dev_err(dev, "error configuring the device: %d\n", ret);
  535. return -ENODEV;
  536. }
  537. hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data,
  538. &ina238_chip_info,
  539. NULL);
  540. if (IS_ERR(hwmon_dev))
  541. return PTR_ERR(hwmon_dev);
  542. dev_info(dev, "power monitor %s (Rshunt = %u uOhm, gain = %u)\n",
  543. client->name, data->rshunt, data->gain);
  544. return 0;
  545. }
  546. static const struct i2c_device_id ina238_id[] = {
  547. { "ina238", 0 },
  548. { }
  549. };
  550. MODULE_DEVICE_TABLE(i2c, ina238_id);
  551. static const struct of_device_id __maybe_unused ina238_of_match[] = {
  552. { .compatible = "ti,ina238" },
  553. { },
  554. };
  555. MODULE_DEVICE_TABLE(of, ina238_of_match);
  556. static struct i2c_driver ina238_driver = {
  557. .class = I2C_CLASS_HWMON,
  558. .driver = {
  559. .name = "ina238",
  560. .of_match_table = of_match_ptr(ina238_of_match),
  561. },
  562. .probe_new = ina238_probe,
  563. .id_table = ina238_id,
  564. };
  565. module_i2c_driver(ina238_driver);
  566. MODULE_AUTHOR("Nathan Rossi <[email protected]>");
  567. MODULE_DESCRIPTION("ina238 driver");
  568. MODULE_LICENSE("GPL");