Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: magnetometer: Add mmc5633 sensor

Add mmc5633 sensor basic support.
- Support read 20 bits X/Y/Z magnetic.
- Support I3C HDR mode to send start measurememt command.
- Support I3C HDR mode to read all sensors data by one command.

Co-developed-by: Carlos Song <carlos.song@nxp.com>
Signed-off-by: Carlos Song <carlos.song@nxp.com>
Co-developed-by: Adrian Fluturel <fluturel.adrian@gmail.com>
Signed-off-by: Adrian Fluturel <fluturel.adrian@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Frank Li and committed by
Jonathan Cameron
6e5f6bf2 419add56

+599
+12
drivers/iio/magnetometer/Kconfig
··· 139 139 To compile this driver as a module, choose M here: the module 140 140 will be called mmc35240. 141 141 142 + config MMC5633 143 + tristate "MEMSIC MMC5633 3-axis magnetic sensor" 144 + select REGMAP_I2C 145 + select REGMAP_I3C 146 + depends on I2C || I3C 147 + help 148 + Say yes here to build support for the MEMSIC MMC5633 3-axis 149 + magnetic sensor. 150 + 151 + To compile this driver as a module, choose M here: the module 152 + will be called mmc5633 153 + 142 154 config IIO_ST_MAGN_3AXIS 143 155 tristate "STMicroelectronics magnetometers 3-Axis Driver" 144 156 depends on (I2C || SPI_MASTER) && SYSFS
+1
drivers/iio/magnetometer/Makefile
··· 15 15 obj-$(CONFIG_MAG3110) += mag3110.o 16 16 obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o 17 17 obj-$(CONFIG_MMC35240) += mmc35240.o 18 + obj-$(CONFIG_MMC5633) += mmc5633.o 18 19 19 20 obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o 20 21 st_magn-y := st_magn_core.o
+586
drivers/iio/magnetometer/mmc5633.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * MMC5633 - MEMSIC 3-axis Magnetic Sensor 4 + * 5 + * Copyright (c) 2015, Intel Corporation. 6 + * Copyright (c) 2025, NXP 7 + * 8 + * IIO driver for MMC5633, base on mmc35240.c 9 + */ 10 + 11 + #include <linux/array_size.h> 12 + #include <linux/bitfield.h> 13 + #include <linux/bits.h> 14 + #include <linux/cleanup.h> 15 + #include <linux/delay.h> 16 + #include <linux/device.h> 17 + #include <linux/dev_printk.h> 18 + #include <linux/err.h> 19 + #include <linux/errno.h> 20 + #include <linux/i2c.h> 21 + #include <linux/i3c/device.h> 22 + #include <linux/iio/iio.h> 23 + #include <linux/iio/sysfs.h> 24 + #include <linux/init.h> 25 + #include <linux/iopoll.h> 26 + #include <linux/module.h> 27 + #include <linux/mod_devicetable.h> 28 + #include <linux/mutex.h> 29 + #include <linux/pm.h> 30 + #include <linux/regmap.h> 31 + #include <linux/time.h> 32 + #include <linux/types.h> 33 + #include <linux/unaligned.h> 34 + 35 + #define MMC5633_REG_XOUT0 0x00 36 + #define MMC5633_REG_XOUT1 0x01 37 + #define MMC5633_REG_YOUT0 0x02 38 + #define MMC5633_REG_YOUT1 0x03 39 + #define MMC5633_REG_ZOUT0 0x04 40 + #define MMC5633_REG_ZOUT1 0x05 41 + #define MMC5633_REG_XOUT2 0x06 42 + #define MMC5633_REG_YOUT2 0x07 43 + #define MMC5633_REG_ZOUT2 0x08 44 + #define MMC5633_REG_TOUT 0x09 45 + 46 + #define MMC5633_REG_STATUS1 0x18 47 + #define MMC5633_REG_STATUS0 0x19 48 + #define MMC5633_REG_CTRL0 0x1b 49 + #define MMC5633_REG_CTRL1 0x1c 50 + #define MMC5633_REG_CTRL2 0x1d 51 + 52 + #define MMC5633_REG_ID 0x39 53 + 54 + #define MMC5633_STATUS1_MEAS_T_DONE_BIT BIT(7) 55 + #define MMC5633_STATUS1_MEAS_M_DONE_BIT BIT(6) 56 + 57 + #define MMC5633_CTRL0_CMM_FREQ_EN BIT(7) 58 + #define MMC5633_CTRL0_AUTO_ST_EN BIT(6) 59 + #define MMC5633_CTRL0_AUTO_SR_EN BIT(5) 60 + #define MMC5633_CTRL0_RESET BIT(4) 61 + #define MMC5633_CTRL0_SET BIT(3) 62 + #define MMC5633_CTRL0_MEAS_T BIT(1) 63 + #define MMC5633_CTRL0_MEAS_M BIT(0) 64 + 65 + #define MMC5633_CTRL1_BW_MASK GENMASK(1, 0) 66 + 67 + #define MMC5633_WAIT_SET_RESET_US (1 * USEC_PER_MSEC) 68 + 69 + #define MMC5633_HDR_CTRL0_MEAS_M 0x01 70 + #define MMC5633_HDR_CTRL0_MEAS_T 0x03 71 + #define MMC5633_HDR_CTRL0_SET 0x05 72 + #define MMC5633_HDR_CTRL0_RESET 0x07 73 + 74 + enum mmc5633_axis { 75 + MMC5633_AXIS_X, 76 + MMC5633_AXIS_Y, 77 + MMC5633_AXIS_Z, 78 + MMC5633_TEMPERATURE, 79 + }; 80 + 81 + struct mmc5633_data { 82 + struct regmap *regmap; 83 + struct i3c_device *i3cdev; 84 + struct mutex mutex; /* protect to finish one whole measurement */ 85 + }; 86 + 87 + static int mmc5633_samp_freq[][2] = { 88 + { 1, 200000 }, 89 + { 2, 0 }, 90 + { 3, 500000 }, 91 + { 6, 600000 }, 92 + }; 93 + 94 + #define MMC5633_CHANNEL(_axis) { \ 95 + .type = IIO_MAGN, \ 96 + .modified = 1, \ 97 + .channel2 = IIO_MOD_ ## _axis, \ 98 + .address = MMC5633_AXIS_ ## _axis, \ 99 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 100 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 101 + BIT(IIO_CHAN_INFO_SCALE), \ 102 + } 103 + 104 + static const struct iio_chan_spec mmc5633_channels[] = { 105 + MMC5633_CHANNEL(X), 106 + MMC5633_CHANNEL(Y), 107 + MMC5633_CHANNEL(Z), 108 + { 109 + .type = IIO_TEMP, 110 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 111 + BIT(IIO_CHAN_INFO_SCALE) | 112 + BIT(IIO_CHAN_INFO_OFFSET), 113 + .address = MMC5633_TEMPERATURE, 114 + }, 115 + }; 116 + 117 + static int mmc5633_get_samp_freq_index(struct mmc5633_data *data, 118 + int val, int val2) 119 + { 120 + unsigned int i; 121 + 122 + for (i = 0; i < ARRAY_SIZE(mmc5633_samp_freq); i++) 123 + if (mmc5633_samp_freq[i][0] == val && 124 + mmc5633_samp_freq[i][1] == val2) 125 + return i; 126 + return -EINVAL; 127 + } 128 + 129 + static int mmc5633_init(struct mmc5633_data *data) 130 + { 131 + unsigned int reg_id; 132 + int ret; 133 + 134 + ret = regmap_read(data->regmap, MMC5633_REG_ID, &reg_id); 135 + if (ret) 136 + return dev_err_probe(regmap_get_device(data->regmap), ret, 137 + "Error reading product id\n"); 138 + 139 + /* 140 + * Make sure we restore sensor characteristics, by doing 141 + * a SET/RESET sequence, the axis polarity being naturally 142 + * aligned after RESET. 143 + */ 144 + ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, MMC5633_CTRL0_SET); 145 + if (ret) 146 + return ret; 147 + 148 + /* 149 + * Minimum time interval between SET or RESET to other operations is 150 + * 1ms according to Operating Timing Diagram in datasheet. 151 + */ 152 + fsleep(MMC5633_WAIT_SET_RESET_US); 153 + 154 + ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, MMC5633_CTRL0_RESET); 155 + if (ret) 156 + return ret; 157 + 158 + /* set default sampling frequency */ 159 + return regmap_update_bits(data->regmap, MMC5633_REG_CTRL1, 160 + MMC5633_CTRL1_BW_MASK, 161 + FIELD_PREP(MMC5633_CTRL1_BW_MASK, 0)); 162 + } 163 + 164 + static int mmc5633_take_measurement(struct mmc5633_data *data, int address) 165 + { 166 + unsigned int reg_status, val; 167 + int ret; 168 + 169 + val = (address == MMC5633_TEMPERATURE) ? MMC5633_CTRL0_MEAS_T : MMC5633_CTRL0_MEAS_M; 170 + ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, val); 171 + if (ret < 0) 172 + return ret; 173 + 174 + val = (address == MMC5633_TEMPERATURE) ? 175 + MMC5633_STATUS1_MEAS_T_DONE_BIT : MMC5633_STATUS1_MEAS_M_DONE_BIT; 176 + ret = regmap_read_poll_timeout(data->regmap, MMC5633_REG_STATUS1, reg_status, 177 + reg_status & val, 178 + 10 * USEC_PER_MSEC, 179 + 100 * 10 * USEC_PER_MSEC); 180 + if (ret) { 181 + dev_err(regmap_get_device(data->regmap), "data not ready\n"); 182 + return ret; 183 + } 184 + 185 + return 0; 186 + } 187 + 188 + static bool mmc5633_is_support_hdr(struct mmc5633_data *data) 189 + { 190 + if (!data->i3cdev) 191 + return false; 192 + 193 + return i3c_device_get_supported_xfer_mode(data->i3cdev) & BIT(I3C_HDR_DDR); 194 + } 195 + 196 + static int mmc5633_read_measurement(struct mmc5633_data *data, int address, void *buf, size_t sz) 197 + { 198 + struct device *dev = regmap_get_device(data->regmap); 199 + u8 data_cmd[2], status[2]; 200 + unsigned int val, ready; 201 + int ret; 202 + 203 + if (mmc5633_is_support_hdr(data)) { 204 + struct i3c_xfer xfers_wr_cmd[] = { 205 + { 206 + .cmd = 0x3b, 207 + .len = 2, 208 + .data.out = data_cmd, 209 + } 210 + }; 211 + struct i3c_xfer xfers_rd_sta_cmd[] = { 212 + { 213 + .cmd = 0x23 | BIT(7), /* RDSTA CMD */ 214 + .len = 2, 215 + .data.in = status, 216 + }, 217 + }; 218 + struct i3c_xfer xfers_rd_data_cmd[] = { 219 + { 220 + .cmd = 0x22 | BIT(7), /* RDLONG CMD */ 221 + .len = sz, 222 + .data.in = buf, 223 + }, 224 + }; 225 + 226 + data_cmd[0] = 0; 227 + data_cmd[1] = (address == MMC5633_TEMPERATURE) ? 228 + MMC5633_HDR_CTRL0_MEAS_T : MMC5633_HDR_CTRL0_MEAS_M; 229 + 230 + ret = i3c_device_do_xfers(data->i3cdev, xfers_wr_cmd, 231 + ARRAY_SIZE(xfers_wr_cmd), I3C_HDR_DDR); 232 + if (ret < 0) 233 + return ret; 234 + 235 + ready = (address == MMC5633_TEMPERATURE) ? 236 + MMC5633_STATUS1_MEAS_T_DONE_BIT : MMC5633_STATUS1_MEAS_M_DONE_BIT; 237 + ret = read_poll_timeout(i3c_device_do_xfers, val, 238 + val || (status[0] & ready), 239 + 10 * USEC_PER_MSEC, 240 + 100 * 10 * USEC_PER_MSEC, 0, 241 + data->i3cdev, xfers_rd_sta_cmd, 242 + ARRAY_SIZE(xfers_rd_sta_cmd), I3C_HDR_DDR); 243 + if (ret) { 244 + dev_err(dev, "data not ready\n"); 245 + return ret; 246 + } 247 + if (val) { 248 + dev_err(dev, "i3c transfer error\n"); 249 + return val; 250 + } 251 + return i3c_device_do_xfers(data->i3cdev, xfers_rd_data_cmd, 252 + ARRAY_SIZE(xfers_rd_data_cmd), I3C_HDR_DDR); 253 + } 254 + 255 + /* Fallback to use SDR/I2C mode */ 256 + ret = mmc5633_take_measurement(data, address); 257 + if (ret < 0) 258 + return ret; 259 + 260 + if (address == MMC5633_TEMPERATURE) 261 + /* 262 + * Put tempeature to last byte of buff to align HDR case. 263 + * I3C will early terminate data read if previous data is not 264 + * available. 265 + */ 266 + return regmap_bulk_read(data->regmap, MMC5633_REG_TOUT, buf + sz - 1, 1); 267 + 268 + return regmap_bulk_read(data->regmap, MMC5633_REG_XOUT0, buf, sz); 269 + } 270 + 271 + /* X,Y,Z 3 channels, each channel has 3 byte and TEMP */ 272 + #define MMC5633_ALL_SIZE (3 * 3 + 1) 273 + 274 + static int mmc5633_get_raw(struct mmc5633_data *data, int index, unsigned char *buf, int *val) 275 + { 276 + if (index == MMC5633_TEMPERATURE) { 277 + *val = buf[MMC5633_ALL_SIZE - 1]; 278 + return 0; 279 + } 280 + /* 281 + * X[19..12] X[11..4] Y[19..12] Y[11..4] Z[19..12] Z[11..4] X[3..0] Y[3..0] Z[3..0] 282 + */ 283 + *val = get_unaligned_be16(buf + 2 * index) << 4; 284 + *val |= buf[index + 6] >> 4; 285 + 286 + return 0; 287 + } 288 + 289 + static int mmc5633_read_raw(struct iio_dev *indio_dev, 290 + struct iio_chan_spec const *chan, int *val, 291 + int *val2, long mask) 292 + { 293 + struct mmc5633_data *data = iio_priv(indio_dev); 294 + char buf[MMC5633_ALL_SIZE]; 295 + unsigned int reg, i; 296 + int ret; 297 + 298 + switch (mask) { 299 + case IIO_CHAN_INFO_RAW: 300 + scoped_guard(mutex, &data->mutex) { 301 + ret = mmc5633_read_measurement(data, chan->address, buf, MMC5633_ALL_SIZE); 302 + if (ret < 0) 303 + return ret; 304 + } 305 + 306 + ret = mmc5633_get_raw(data, chan->address, buf, val); 307 + if (ret < 0) 308 + return ret; 309 + return IIO_VAL_INT; 310 + case IIO_CHAN_INFO_SCALE: 311 + if (chan->type == IIO_MAGN) { 312 + *val = 0; 313 + *val2 = 62500; 314 + } else { 315 + *val = 0; 316 + *val2 = 800000000; /* 0.8C */ 317 + } 318 + return IIO_VAL_INT_PLUS_NANO; 319 + case IIO_CHAN_INFO_OFFSET: 320 + if (chan->type == IIO_TEMP) { 321 + *val = -75; 322 + return IIO_VAL_INT; 323 + } 324 + return -EINVAL; 325 + case IIO_CHAN_INFO_SAMP_FREQ: 326 + scoped_guard(mutex, &data->mutex) { 327 + ret = regmap_read(data->regmap, MMC5633_REG_CTRL1, &reg); 328 + if (ret < 0) 329 + return ret; 330 + } 331 + 332 + i = FIELD_GET(MMC5633_CTRL1_BW_MASK, reg); 333 + if (i >= ARRAY_SIZE(mmc5633_samp_freq)) 334 + return -EINVAL; 335 + 336 + *val = mmc5633_samp_freq[i][0]; 337 + *val2 = mmc5633_samp_freq[i][1]; 338 + return IIO_VAL_INT_PLUS_MICRO; 339 + default: 340 + return -EINVAL; 341 + } 342 + } 343 + 344 + static int mmc5633_write_raw(struct iio_dev *indio_dev, 345 + struct iio_chan_spec const *chan, int val, 346 + int val2, long mask) 347 + { 348 + struct mmc5633_data *data = iio_priv(indio_dev); 349 + int ret; 350 + 351 + switch (mask) { 352 + case IIO_CHAN_INFO_SAMP_FREQ: { 353 + ret = mmc5633_get_samp_freq_index(data, val, val2); 354 + if (ret < 0) 355 + return ret; 356 + 357 + guard(mutex)(&data->mutex); 358 + 359 + return regmap_update_bits(data->regmap, MMC5633_REG_CTRL1, 360 + MMC5633_CTRL1_BW_MASK, 361 + FIELD_PREP(MMC5633_CTRL1_BW_MASK, ret)); 362 + } 363 + default: 364 + return -EINVAL; 365 + } 366 + } 367 + 368 + static int mmc5633_read_avail(struct iio_dev *indio_dev, 369 + struct iio_chan_spec const *chan, 370 + const int **vals, int *type, int *length, 371 + long mask) 372 + { 373 + switch (mask) { 374 + case IIO_CHAN_INFO_SAMP_FREQ: 375 + *vals = (const int *)mmc5633_samp_freq; 376 + *length = ARRAY_SIZE(mmc5633_samp_freq) * 2; 377 + *type = IIO_VAL_INT_PLUS_MICRO; 378 + return IIO_AVAIL_LIST; 379 + default: 380 + return -EINVAL; 381 + } 382 + } 383 + 384 + static const struct iio_info mmc5633_info = { 385 + .read_raw = mmc5633_read_raw, 386 + .write_raw = mmc5633_write_raw, 387 + .read_avail = mmc5633_read_avail, 388 + }; 389 + 390 + static bool mmc5633_is_writeable_reg(struct device *dev, unsigned int reg) 391 + { 392 + switch (reg) { 393 + case MMC5633_REG_CTRL0: 394 + case MMC5633_REG_CTRL1: 395 + return true; 396 + default: 397 + return false; 398 + } 399 + } 400 + 401 + static bool mmc5633_is_readable_reg(struct device *dev, unsigned int reg) 402 + { 403 + switch (reg) { 404 + case MMC5633_REG_XOUT0: 405 + case MMC5633_REG_XOUT1: 406 + case MMC5633_REG_YOUT0: 407 + case MMC5633_REG_YOUT1: 408 + case MMC5633_REG_ZOUT0: 409 + case MMC5633_REG_ZOUT1: 410 + case MMC5633_REG_XOUT2: 411 + case MMC5633_REG_YOUT2: 412 + case MMC5633_REG_ZOUT2: 413 + case MMC5633_REG_TOUT: 414 + case MMC5633_REG_STATUS1: 415 + case MMC5633_REG_ID: 416 + return true; 417 + default: 418 + return false; 419 + } 420 + } 421 + 422 + static bool mmc5633_is_volatile_reg(struct device *dev, unsigned int reg) 423 + { 424 + switch (reg) { 425 + case MMC5633_REG_CTRL0: 426 + case MMC5633_REG_CTRL1: 427 + return false; 428 + default: 429 + return true; 430 + } 431 + } 432 + 433 + static const struct reg_default mmc5633_reg_defaults[] = { 434 + { MMC5633_REG_CTRL0, 0x00 }, 435 + { MMC5633_REG_CTRL1, 0x00 }, 436 + }; 437 + 438 + static const struct regmap_config mmc5633_regmap_config = { 439 + .name = "mmc5633_regmap", 440 + 441 + .reg_bits = 8, 442 + .val_bits = 8, 443 + 444 + .max_register = MMC5633_REG_ID, 445 + .cache_type = REGCACHE_MAPLE, 446 + 447 + .writeable_reg = mmc5633_is_writeable_reg, 448 + .readable_reg = mmc5633_is_readable_reg, 449 + .volatile_reg = mmc5633_is_volatile_reg, 450 + 451 + .reg_defaults = mmc5633_reg_defaults, 452 + .num_reg_defaults = ARRAY_SIZE(mmc5633_reg_defaults), 453 + }; 454 + 455 + static int mmc5633_common_probe(struct regmap *regmap, char *name, 456 + struct i3c_device *i3cdev) 457 + { 458 + struct device *dev = regmap_get_device(regmap); 459 + struct mmc5633_data *data; 460 + struct iio_dev *indio_dev; 461 + int ret; 462 + 463 + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 464 + if (!indio_dev) 465 + return -ENOMEM; 466 + 467 + data = iio_priv(indio_dev); 468 + 469 + data->regmap = regmap; 470 + data->i3cdev = i3cdev; 471 + 472 + ret = devm_mutex_init(dev, &data->mutex); 473 + if (ret) 474 + return ret; 475 + 476 + indio_dev->info = &mmc5633_info; 477 + indio_dev->name = name; 478 + indio_dev->channels = mmc5633_channels; 479 + indio_dev->num_channels = ARRAY_SIZE(mmc5633_channels); 480 + indio_dev->modes = INDIO_DIRECT_MODE; 481 + 482 + ret = mmc5633_init(data); 483 + if (ret < 0) 484 + return dev_err_probe(dev, ret, "mmc5633 chip init failed\n"); 485 + 486 + return devm_iio_device_register(dev, indio_dev); 487 + } 488 + 489 + static int mmc5633_suspend(struct device *dev) 490 + { 491 + struct regmap *regmap = dev_get_regmap(dev, NULL); 492 + 493 + regcache_cache_only(regmap, true); 494 + 495 + return 0; 496 + } 497 + 498 + static int mmc5633_resume(struct device *dev) 499 + { 500 + struct regmap *regmap = dev_get_regmap(dev, NULL); 501 + int ret; 502 + 503 + regcache_mark_dirty(regmap); 504 + ret = regcache_sync_region(regmap, MMC5633_REG_CTRL0, MMC5633_REG_CTRL1); 505 + if (ret) 506 + dev_err(dev, "Failed to restore control registers\n"); 507 + 508 + regcache_cache_only(regmap, false); 509 + 510 + return 0; 511 + } 512 + 513 + static int mmc5633_i2c_probe(struct i2c_client *client) 514 + { 515 + struct device *dev = &client->dev; 516 + struct regmap *regmap; 517 + 518 + regmap = devm_regmap_init_i2c(client, &mmc5633_regmap_config); 519 + if (IS_ERR(regmap)) 520 + return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n"); 521 + 522 + return mmc5633_common_probe(regmap, client->name, NULL); 523 + } 524 + 525 + static DEFINE_SIMPLE_DEV_PM_OPS(mmc5633_pm_ops, mmc5633_suspend, mmc5633_resume); 526 + 527 + static const struct of_device_id mmc5633_of_match[] = { 528 + { .compatible = "memsic,mmc5603" }, 529 + { .compatible = "memsic,mmc5633" }, 530 + { } 531 + }; 532 + MODULE_DEVICE_TABLE(of, mmc5633_of_match); 533 + 534 + static const struct i2c_device_id mmc5633_i2c_id[] = { 535 + { "mmc5603" }, 536 + { "mmc5633" }, 537 + { } 538 + }; 539 + MODULE_DEVICE_TABLE(i2c, mmc5633_i2c_id); 540 + 541 + static struct i2c_driver mmc5633_i2c_driver = { 542 + .driver = { 543 + .name = "mmc5633_i2c", 544 + .of_match_table = mmc5633_of_match, 545 + .pm = pm_sleep_ptr(&mmc5633_pm_ops), 546 + }, 547 + .probe = mmc5633_i2c_probe, 548 + .id_table = mmc5633_i2c_id, 549 + }; 550 + 551 + static const struct i3c_device_id mmc5633_i3c_ids[] = { 552 + I3C_DEVICE(0x0251, 0x0000, NULL), 553 + { } 554 + }; 555 + MODULE_DEVICE_TABLE(i3c, mmc5633_i3c_ids); 556 + 557 + static int mmc5633_i3c_probe(struct i3c_device *i3cdev) 558 + { 559 + struct device *dev = i3cdev_to_dev(i3cdev); 560 + struct regmap *regmap; 561 + char *name; 562 + 563 + name = devm_kasprintf(dev, GFP_KERNEL, "mmc5633_%s", dev_name(dev)); 564 + if (!name) 565 + return -ENOMEM; 566 + 567 + regmap = devm_regmap_init_i3c(i3cdev, &mmc5633_regmap_config); 568 + if (IS_ERR(regmap)) 569 + return dev_err_probe(dev, PTR_ERR(regmap), 570 + "Failed to register i3c regmap\n"); 571 + 572 + return mmc5633_common_probe(regmap, name, i3cdev); 573 + } 574 + 575 + static struct i3c_driver mmc5633_i3c_driver = { 576 + .driver = { 577 + .name = "mmc5633_i3c", 578 + }, 579 + .probe = mmc5633_i3c_probe, 580 + .id_table = mmc5633_i3c_ids, 581 + }; 582 + module_i3c_i2c_driver(mmc5633_i3c_driver, &mmc5633_i2c_driver) 583 + 584 + MODULE_AUTHOR("Frank Li <Frank.li@nxp.com>"); 585 + MODULE_DESCRIPTION("MEMSIC MMC5633 magnetic sensor driver"); 586 + MODULE_LICENSE("GPL");