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

mfd: Add Intel MSIC driver

Add support for Intel MSIC chip found on Intel Medfield platforms. This
chip embeds several subdevices: audio, ADC, GPIO, power button, etc. The
driver creates platform device for each subdevice.

We also provide an MSIC register access API which should replace the more
generic SCU IPC interface currently used. Existing drivers can choose
whether they convert to this new API or stick with the SCU IPC interface.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Mika Westerberg and committed by
Samuel Ortiz
1f5a371c 429c9ecc

+967
+9
drivers/mfd/Kconfig
··· 757 757 additional drivers must be enabled in order to use the 758 758 functionality of the device. 759 759 760 + config MFD_INTEL_MSIC 761 + bool "Support for Intel MSIC" 762 + depends on INTEL_SCU_IPC 763 + select MFD_CORE 764 + help 765 + Select this option to enable access to Intel MSIC (Avatele 766 + Passage) chip. This chip embeds audio, battery, GPIO, etc. 767 + devices used in Intel Medfield platforms. 768 + 760 769 endmenu 761 770 endif 762 771
+1
drivers/mfd/Makefile
··· 102 102 obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o 103 103 obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o 104 104 obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o 105 + obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
+501
drivers/mfd/intel_msic.c
··· 1 + /* 2 + * Driver for Intel MSIC 3 + * 4 + * Copyright (C) 2011, Intel Corporation 5 + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/gpio.h> 13 + #include <linux/module.h> 14 + #include <linux/mfd/core.h> 15 + #include <linux/mfd/intel_msic.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/slab.h> 18 + 19 + #include <asm/intel_scu_ipc.h> 20 + 21 + #define MSIC_VENDOR(id) ((id >> 6) & 3) 22 + #define MSIC_VERSION(id) (id & 0x3f) 23 + #define MSIC_MAJOR(id) ('A' + ((id >> 3) & 7)) 24 + #define MSIC_MINOR(id) (id & 7) 25 + 26 + /* 27 + * MSIC interrupt tree is readable from SRAM at INTEL_MSIC_IRQ_PHYS_BASE. 28 + * Since IRQ block starts from address 0x002 we need to substract that from 29 + * the actual IRQ status register address. 30 + */ 31 + #define MSIC_IRQ_STATUS(x) (INTEL_MSIC_IRQ_PHYS_BASE + ((x) - 2)) 32 + #define MSIC_IRQ_STATUS_ACCDET MSIC_IRQ_STATUS(INTEL_MSIC_ACCDET) 33 + 34 + /* 35 + * The SCU hardware has limitation of 16 bytes per read/write buffer on 36 + * Medfield. 37 + */ 38 + #define SCU_IPC_RWBUF_LIMIT 16 39 + 40 + /** 41 + * struct intel_msic - an MSIC MFD instance 42 + * @pdev: pointer to the platform device 43 + * @vendor: vendor ID 44 + * @version: chip version 45 + * @irq_base: base address of the mapped MSIC SRAM interrupt tree 46 + */ 47 + struct intel_msic { 48 + struct platform_device *pdev; 49 + unsigned vendor; 50 + unsigned version; 51 + void __iomem *irq_base; 52 + }; 53 + 54 + static struct resource msic_touch_resources[] = { 55 + { 56 + .flags = IORESOURCE_IRQ, 57 + }, 58 + }; 59 + 60 + static struct resource msic_adc_resources[] = { 61 + { 62 + .flags = IORESOURCE_IRQ, 63 + }, 64 + }; 65 + 66 + static struct resource msic_battery_resources[] = { 67 + { 68 + .flags = IORESOURCE_IRQ, 69 + }, 70 + }; 71 + 72 + static struct resource msic_gpio_resources[] = { 73 + { 74 + .flags = IORESOURCE_IRQ, 75 + }, 76 + }; 77 + 78 + static struct resource msic_audio_resources[] = { 79 + { 80 + .name = "IRQ", 81 + .flags = IORESOURCE_IRQ, 82 + }, 83 + /* 84 + * We will pass IRQ_BASE to the driver now but this can be removed 85 + * when/if the driver starts to use intel_msic_irq_read(). 86 + */ 87 + { 88 + .name = "IRQ_BASE", 89 + .flags = IORESOURCE_MEM, 90 + .start = MSIC_IRQ_STATUS_ACCDET, 91 + .end = MSIC_IRQ_STATUS_ACCDET, 92 + }, 93 + }; 94 + 95 + static struct resource msic_hdmi_resources[] = { 96 + { 97 + .flags = IORESOURCE_IRQ, 98 + }, 99 + }; 100 + 101 + static struct resource msic_thermal_resources[] = { 102 + { 103 + .flags = IORESOURCE_IRQ, 104 + }, 105 + }; 106 + 107 + static struct resource msic_power_btn_resources[] = { 108 + { 109 + .flags = IORESOURCE_IRQ, 110 + }, 111 + }; 112 + 113 + static struct resource msic_ocd_resources[] = { 114 + { 115 + .flags = IORESOURCE_IRQ, 116 + }, 117 + }; 118 + 119 + /* 120 + * Devices that are part of the MSIC and are available via firmware 121 + * populated SFI DEVS table. 122 + */ 123 + static struct mfd_cell msic_devs[] = { 124 + [INTEL_MSIC_BLOCK_TOUCH] = { 125 + .name = "msic_touch", 126 + .num_resources = ARRAY_SIZE(msic_touch_resources), 127 + .resources = msic_touch_resources, 128 + }, 129 + [INTEL_MSIC_BLOCK_ADC] = { 130 + .name = "msic_adc", 131 + .num_resources = ARRAY_SIZE(msic_adc_resources), 132 + .resources = msic_adc_resources, 133 + }, 134 + [INTEL_MSIC_BLOCK_BATTERY] = { 135 + .name = "msic_battery", 136 + .num_resources = ARRAY_SIZE(msic_battery_resources), 137 + .resources = msic_battery_resources, 138 + }, 139 + [INTEL_MSIC_BLOCK_GPIO] = { 140 + .name = "msic_gpio", 141 + .num_resources = ARRAY_SIZE(msic_gpio_resources), 142 + .resources = msic_gpio_resources, 143 + }, 144 + [INTEL_MSIC_BLOCK_AUDIO] = { 145 + .name = "msic_audio", 146 + .num_resources = ARRAY_SIZE(msic_audio_resources), 147 + .resources = msic_audio_resources, 148 + }, 149 + [INTEL_MSIC_BLOCK_HDMI] = { 150 + .name = "msic_hdmi", 151 + .num_resources = ARRAY_SIZE(msic_hdmi_resources), 152 + .resources = msic_hdmi_resources, 153 + }, 154 + [INTEL_MSIC_BLOCK_THERMAL] = { 155 + .name = "msic_thermal", 156 + .num_resources = ARRAY_SIZE(msic_thermal_resources), 157 + .resources = msic_thermal_resources, 158 + }, 159 + [INTEL_MSIC_BLOCK_POWER_BTN] = { 160 + .name = "msic_power_btn", 161 + .num_resources = ARRAY_SIZE(msic_power_btn_resources), 162 + .resources = msic_power_btn_resources, 163 + }, 164 + [INTEL_MSIC_BLOCK_OCD] = { 165 + .name = "msic_ocd", 166 + .num_resources = ARRAY_SIZE(msic_ocd_resources), 167 + .resources = msic_ocd_resources, 168 + }, 169 + }; 170 + 171 + /* 172 + * Other MSIC related devices which are not directly available via SFI DEVS 173 + * table. These can be pseudo devices, regulators etc. which are needed for 174 + * different purposes. 175 + * 176 + * These devices appear only after the MSIC driver itself is initialized so 177 + * we can guarantee that the SCU IPC interface is ready. 178 + */ 179 + static struct mfd_cell msic_other_devs[] = { 180 + /* Audio codec in the MSIC */ 181 + { 182 + .id = -1, 183 + .name = "sn95031", 184 + }, 185 + }; 186 + 187 + /** 188 + * intel_msic_reg_read - read a single MSIC register 189 + * @reg: register to read 190 + * @val: register value is placed here 191 + * 192 + * Read a single register from MSIC. Returns %0 on success and negative 193 + * errno in case of failure. 194 + * 195 + * Function may sleep. 196 + */ 197 + int intel_msic_reg_read(unsigned short reg, u8 *val) 198 + { 199 + return intel_scu_ipc_ioread8(reg, val); 200 + } 201 + EXPORT_SYMBOL_GPL(intel_msic_reg_read); 202 + 203 + /** 204 + * intel_msic_reg_write - write a single MSIC register 205 + * @reg: register to write 206 + * @val: value to write to that register 207 + * 208 + * Write a single MSIC register. Returns 0 on success and negative 209 + * errno in case of failure. 210 + * 211 + * Function may sleep. 212 + */ 213 + int intel_msic_reg_write(unsigned short reg, u8 val) 214 + { 215 + return intel_scu_ipc_iowrite8(reg, val); 216 + } 217 + EXPORT_SYMBOL_GPL(intel_msic_reg_write); 218 + 219 + /** 220 + * intel_msic_reg_update - update a single MSIC register 221 + * @reg: register to update 222 + * @val: value to write to the register 223 + * @mask: specifies which of the bits are updated (%0 = don't update, 224 + * %1 = update) 225 + * 226 + * Perform an update to a register @reg. @mask is used to specify which 227 + * bits are updated. Returns %0 in case of success and negative errno in 228 + * case of failure. 229 + * 230 + * Function may sleep. 231 + */ 232 + int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask) 233 + { 234 + return intel_scu_ipc_update_register(reg, val, mask); 235 + } 236 + EXPORT_SYMBOL_GPL(intel_msic_reg_update); 237 + 238 + /** 239 + * intel_msic_bulk_read - read an array of registers 240 + * @reg: array of register addresses to read 241 + * @buf: array where the read values are placed 242 + * @count: number of registers to read 243 + * 244 + * Function reads @count registers from the MSIC using addresses passed in 245 + * @reg. Read values are placed in @buf. Reads are performed atomically 246 + * wrt. MSIC. 247 + * 248 + * Returns %0 in case of success and negative errno in case of failure. 249 + * 250 + * Function may sleep. 251 + */ 252 + int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count) 253 + { 254 + if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT)) 255 + return -EINVAL; 256 + 257 + return intel_scu_ipc_readv(reg, buf, count); 258 + } 259 + EXPORT_SYMBOL_GPL(intel_msic_bulk_read); 260 + 261 + /** 262 + * intel_msic_bulk_write - write an array of values to the MSIC registers 263 + * @reg: array of registers to write 264 + * @buf: values to write to each register 265 + * @count: number of registers to write 266 + * 267 + * Function writes @count registers in @buf to MSIC. Writes are performed 268 + * atomically wrt MSIC. Returns %0 in case of success and negative errno in 269 + * case of failure. 270 + * 271 + * Function may sleep. 272 + */ 273 + int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count) 274 + { 275 + if (WARN_ON(count > SCU_IPC_RWBUF_LIMIT)) 276 + return -EINVAL; 277 + 278 + return intel_scu_ipc_writev(reg, buf, count); 279 + } 280 + EXPORT_SYMBOL_GPL(intel_msic_bulk_write); 281 + 282 + /** 283 + * intel_msic_irq_read - read a register from an MSIC interrupt tree 284 + * @msic: MSIC instance 285 + * @reg: interrupt register (between %INTEL_MSIC_IRQLVL1 and 286 + * %INTEL_MSIC_RESETIRQ2) 287 + * @val: value of the register is placed here 288 + * 289 + * This function can be used by an MSIC subdevice interrupt handler to read 290 + * a register value from the MSIC interrupt tree. In this way subdevice 291 + * drivers don't have to map in the interrupt tree themselves but can just 292 + * call this function instead. 293 + * 294 + * Function doesn't sleep and is callable from interrupt context. 295 + * 296 + * Returns %-EINVAL if @reg is outside of the allowed register region. 297 + */ 298 + int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, u8 *val) 299 + { 300 + if (WARN_ON(reg < INTEL_MSIC_IRQLVL1 || reg > INTEL_MSIC_RESETIRQ2)) 301 + return -EINVAL; 302 + 303 + *val = readb(msic->irq_base + (reg - INTEL_MSIC_IRQLVL1)); 304 + return 0; 305 + } 306 + EXPORT_SYMBOL_GPL(intel_msic_irq_read); 307 + 308 + static int __devinit intel_msic_init_devices(struct intel_msic *msic) 309 + { 310 + struct platform_device *pdev = msic->pdev; 311 + struct intel_msic_platform_data *pdata = pdev->dev.platform_data; 312 + int ret, i; 313 + 314 + if (pdata->gpio) { 315 + struct mfd_cell *cell = &msic_devs[INTEL_MSIC_BLOCK_GPIO]; 316 + 317 + cell->platform_data = pdata->gpio; 318 + cell->pdata_size = sizeof(*pdata->gpio); 319 + } 320 + 321 + if (pdata->ocd) { 322 + unsigned gpio = pdata->ocd->gpio; 323 + 324 + ret = gpio_request_one(gpio, GPIOF_IN, "ocd_gpio"); 325 + if (ret) { 326 + dev_err(&pdev->dev, "failed to register OCD GPIO\n"); 327 + return ret; 328 + } 329 + 330 + ret = gpio_to_irq(gpio); 331 + if (ret < 0) { 332 + dev_err(&pdev->dev, "no IRQ number for OCD GPIO\n"); 333 + gpio_free(gpio); 334 + return ret; 335 + } 336 + 337 + /* Update the IRQ number for the OCD */ 338 + pdata->irq[INTEL_MSIC_BLOCK_OCD] = ret; 339 + } 340 + 341 + for (i = 0; i < ARRAY_SIZE(msic_devs); i++) { 342 + if (!pdata->irq[i]) 343 + continue; 344 + 345 + ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, 346 + pdata->irq[i]); 347 + if (ret) 348 + goto fail; 349 + } 350 + 351 + ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, 352 + ARRAY_SIZE(msic_other_devs), NULL, 0); 353 + if (ret) 354 + goto fail; 355 + 356 + return 0; 357 + 358 + fail: 359 + mfd_remove_devices(&pdev->dev); 360 + if (pdata->ocd) 361 + gpio_free(pdata->ocd->gpio); 362 + 363 + return ret; 364 + } 365 + 366 + static void __devexit intel_msic_remove_devices(struct intel_msic *msic) 367 + { 368 + struct platform_device *pdev = msic->pdev; 369 + struct intel_msic_platform_data *pdata = pdev->dev.platform_data; 370 + 371 + mfd_remove_devices(&pdev->dev); 372 + 373 + if (pdata->ocd) 374 + gpio_free(pdata->ocd->gpio); 375 + } 376 + 377 + static int __devinit intel_msic_probe(struct platform_device *pdev) 378 + { 379 + struct intel_msic_platform_data *pdata = pdev->dev.platform_data; 380 + struct intel_msic *msic; 381 + struct resource *res; 382 + u8 id0, id1; 383 + int ret; 384 + 385 + if (!pdata) { 386 + dev_err(&pdev->dev, "no platform data passed\n"); 387 + return -EINVAL; 388 + } 389 + 390 + /* First validate that we have an MSIC in place */ 391 + ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID0, &id0); 392 + if (ret) { 393 + dev_err(&pdev->dev, "failed to identify the MSIC chip (ID0)\n"); 394 + return -ENXIO; 395 + } 396 + 397 + ret = intel_scu_ipc_ioread8(INTEL_MSIC_ID1, &id1); 398 + if (ret) { 399 + dev_err(&pdev->dev, "failed to identify the MSIC chip (ID1)\n"); 400 + return -ENXIO; 401 + } 402 + 403 + if (MSIC_VENDOR(id0) != MSIC_VENDOR(id1)) { 404 + dev_err(&pdev->dev, "invalid vendor ID: %x, %x\n", id0, id1); 405 + return -ENXIO; 406 + } 407 + 408 + msic = kzalloc(sizeof(*msic), GFP_KERNEL); 409 + if (!msic) 410 + return -ENOMEM; 411 + 412 + msic->vendor = MSIC_VENDOR(id0); 413 + msic->version = MSIC_VERSION(id0); 414 + msic->pdev = pdev; 415 + 416 + /* 417 + * Map in the MSIC interrupt tree area in SRAM. This is exposed to 418 + * the clients via intel_msic_irq_read(). 419 + */ 420 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 421 + if (!res) { 422 + dev_err(&pdev->dev, "failed to get SRAM iomem resource\n"); 423 + ret = -ENODEV; 424 + goto fail_free_msic; 425 + } 426 + 427 + res = request_mem_region(res->start, resource_size(res), pdev->name); 428 + if (!res) { 429 + ret = -EBUSY; 430 + goto fail_free_msic; 431 + } 432 + 433 + msic->irq_base = ioremap_nocache(res->start, resource_size(res)); 434 + if (!msic->irq_base) { 435 + dev_err(&pdev->dev, "failed to map SRAM memory\n"); 436 + ret = -ENOMEM; 437 + goto fail_release_region; 438 + } 439 + 440 + platform_set_drvdata(pdev, msic); 441 + 442 + ret = intel_msic_init_devices(msic); 443 + if (ret) { 444 + dev_err(&pdev->dev, "failed to initialize MSIC devices\n"); 445 + goto fail_unmap_mem; 446 + } 447 + 448 + dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n", 449 + MSIC_MAJOR(msic->version), MSIC_MINOR(msic->version), 450 + msic->vendor); 451 + 452 + return 0; 453 + 454 + fail_unmap_mem: 455 + iounmap(msic->irq_base); 456 + fail_release_region: 457 + release_mem_region(res->start, resource_size(res)); 458 + fail_free_msic: 459 + kfree(msic); 460 + 461 + return ret; 462 + } 463 + 464 + static int __devexit intel_msic_remove(struct platform_device *pdev) 465 + { 466 + struct intel_msic *msic = platform_get_drvdata(pdev); 467 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 468 + 469 + intel_msic_remove_devices(msic); 470 + platform_set_drvdata(pdev, NULL); 471 + iounmap(msic->irq_base); 472 + release_mem_region(res->start, resource_size(res)); 473 + kfree(msic); 474 + 475 + return 0; 476 + } 477 + 478 + static struct platform_driver intel_msic_driver = { 479 + .probe = intel_msic_probe, 480 + .remove = __devexit_p(intel_msic_remove), 481 + .driver = { 482 + .name = "intel_msic", 483 + .owner = THIS_MODULE, 484 + }, 485 + }; 486 + 487 + static int __init intel_msic_init(void) 488 + { 489 + return platform_driver_register(&intel_msic_driver); 490 + } 491 + module_init(intel_msic_init); 492 + 493 + static void __exit intel_msic_exit(void) 494 + { 495 + platform_driver_unregister(&intel_msic_driver); 496 + } 497 + module_exit(intel_msic_exit); 498 + 499 + MODULE_DESCRIPTION("Driver for Intel MSIC"); 500 + MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 501 + MODULE_LICENSE("GPL");
+456
include/linux/mfd/intel_msic.h
··· 1 + /* 2 + * include/linux/mfd/intel_msic.h - Core interface for Intel MSIC 3 + * 4 + * Copyright (C) 2011, Intel Corporation 5 + * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #ifndef __LINUX_MFD_INTEL_MSIC_H__ 13 + #define __LINUX_MFD_INTEL_MSIC_H__ 14 + 15 + /* ID */ 16 + #define INTEL_MSIC_ID0 0x000 /* RO */ 17 + #define INTEL_MSIC_ID1 0x001 /* RO */ 18 + 19 + /* IRQ */ 20 + #define INTEL_MSIC_IRQLVL1 0x002 21 + #define INTEL_MSIC_ADC1INT 0x003 22 + #define INTEL_MSIC_CCINT 0x004 23 + #define INTEL_MSIC_PWRSRCINT 0x005 24 + #define INTEL_MSIC_PWRSRCINT1 0x006 25 + #define INTEL_MSIC_CHRINT 0x007 26 + #define INTEL_MSIC_CHRINT1 0x008 27 + #define INTEL_MSIC_RTCIRQ 0x009 28 + #define INTEL_MSIC_GPIO0LVIRQ 0x00a 29 + #define INTEL_MSIC_GPIO1LVIRQ 0x00b 30 + #define INTEL_MSIC_GPIOHVIRQ 0x00c 31 + #define INTEL_MSIC_VRINT 0x00d 32 + #define INTEL_MSIC_OCAUDIO 0x00e 33 + #define INTEL_MSIC_ACCDET 0x00f 34 + #define INTEL_MSIC_RESETIRQ1 0x010 35 + #define INTEL_MSIC_RESETIRQ2 0x011 36 + #define INTEL_MSIC_MADC1INT 0x012 37 + #define INTEL_MSIC_MCCINT 0x013 38 + #define INTEL_MSIC_MPWRSRCINT 0x014 39 + #define INTEL_MSIC_MPWRSRCINT1 0x015 40 + #define INTEL_MSIC_MCHRINT 0x016 41 + #define INTEL_MSIC_MCHRINT1 0x017 42 + #define INTEL_MSIC_RTCIRQMASK 0x018 43 + #define INTEL_MSIC_GPIO0LVIRQMASK 0x019 44 + #define INTEL_MSIC_GPIO1LVIRQMASK 0x01a 45 + #define INTEL_MSIC_GPIOHVIRQMASK 0x01b 46 + #define INTEL_MSIC_VRINTMASK 0x01c 47 + #define INTEL_MSIC_OCAUDIOMASK 0x01d 48 + #define INTEL_MSIC_ACCDETMASK 0x01e 49 + #define INTEL_MSIC_RESETIRQ1MASK 0x01f 50 + #define INTEL_MSIC_RESETIRQ2MASK 0x020 51 + #define INTEL_MSIC_IRQLVL1MSK 0x021 52 + #define INTEL_MSIC_PBCONFIG 0x03e 53 + #define INTEL_MSIC_PBSTATUS 0x03f /* RO */ 54 + 55 + /* GPIO */ 56 + #define INTEL_MSIC_GPIO0LV7CTLO 0x040 57 + #define INTEL_MSIC_GPIO0LV6CTLO 0x041 58 + #define INTEL_MSIC_GPIO0LV5CTLO 0x042 59 + #define INTEL_MSIC_GPIO0LV4CTLO 0x043 60 + #define INTEL_MSIC_GPIO0LV3CTLO 0x044 61 + #define INTEL_MSIC_GPIO0LV2CTLO 0x045 62 + #define INTEL_MSIC_GPIO0LV1CTLO 0x046 63 + #define INTEL_MSIC_GPIO0LV0CTLO 0x047 64 + #define INTEL_MSIC_GPIO1LV7CTLOS 0x048 65 + #define INTEL_MSIC_GPIO1LV6CTLO 0x049 66 + #define INTEL_MSIC_GPIO1LV5CTLO 0x04a 67 + #define INTEL_MSIC_GPIO1LV4CTLO 0x04b 68 + #define INTEL_MSIC_GPIO1LV3CTLO 0x04c 69 + #define INTEL_MSIC_GPIO1LV2CTLO 0x04d 70 + #define INTEL_MSIC_GPIO1LV1CTLO 0x04e 71 + #define INTEL_MSIC_GPIO1LV0CTLO 0x04f 72 + #define INTEL_MSIC_GPIO0LV7CTLI 0x050 73 + #define INTEL_MSIC_GPIO0LV6CTLI 0x051 74 + #define INTEL_MSIC_GPIO0LV5CTLI 0x052 75 + #define INTEL_MSIC_GPIO0LV4CTLI 0x053 76 + #define INTEL_MSIC_GPIO0LV3CTLI 0x054 77 + #define INTEL_MSIC_GPIO0LV2CTLI 0x055 78 + #define INTEL_MSIC_GPIO0LV1CTLI 0x056 79 + #define INTEL_MSIC_GPIO0LV0CTLI 0x057 80 + #define INTEL_MSIC_GPIO1LV7CTLIS 0x058 81 + #define INTEL_MSIC_GPIO1LV6CTLI 0x059 82 + #define INTEL_MSIC_GPIO1LV5CTLI 0x05a 83 + #define INTEL_MSIC_GPIO1LV4CTLI 0x05b 84 + #define INTEL_MSIC_GPIO1LV3CTLI 0x05c 85 + #define INTEL_MSIC_GPIO1LV2CTLI 0x05d 86 + #define INTEL_MSIC_GPIO1LV1CTLI 0x05e 87 + #define INTEL_MSIC_GPIO1LV0CTLI 0x05f 88 + #define INTEL_MSIC_PWM0CLKDIV1 0x061 89 + #define INTEL_MSIC_PWM0CLKDIV0 0x062 90 + #define INTEL_MSIC_PWM1CLKDIV1 0x063 91 + #define INTEL_MSIC_PWM1CLKDIV0 0x064 92 + #define INTEL_MSIC_PWM2CLKDIV1 0x065 93 + #define INTEL_MSIC_PWM2CLKDIV0 0x066 94 + #define INTEL_MSIC_PWM0DUTYCYCLE 0x067 95 + #define INTEL_MSIC_PWM1DUTYCYCLE 0x068 96 + #define INTEL_MSIC_PWM2DUTYCYCLE 0x069 97 + #define INTEL_MSIC_GPIO0HV3CTLO 0x06d 98 + #define INTEL_MSIC_GPIO0HV2CTLO 0x06e 99 + #define INTEL_MSIC_GPIO0HV1CTLO 0x06f 100 + #define INTEL_MSIC_GPIO0HV0CTLO 0x070 101 + #define INTEL_MSIC_GPIO1HV3CTLO 0x071 102 + #define INTEL_MSIC_GPIO1HV2CTLO 0x072 103 + #define INTEL_MSIC_GPIO1HV1CTLO 0x073 104 + #define INTEL_MSIC_GPIO1HV0CTLO 0x074 105 + #define INTEL_MSIC_GPIO0HV3CTLI 0x075 106 + #define INTEL_MSIC_GPIO0HV2CTLI 0x076 107 + #define INTEL_MSIC_GPIO0HV1CTLI 0x077 108 + #define INTEL_MSIC_GPIO0HV0CTLI 0x078 109 + #define INTEL_MSIC_GPIO1HV3CTLI 0x079 110 + #define INTEL_MSIC_GPIO1HV2CTLI 0x07a 111 + #define INTEL_MSIC_GPIO1HV1CTLI 0x07b 112 + #define INTEL_MSIC_GPIO1HV0CTLI 0x07c 113 + 114 + /* SVID */ 115 + #define INTEL_MSIC_SVIDCTRL0 0x080 116 + #define INTEL_MSIC_SVIDCTRL1 0x081 117 + #define INTEL_MSIC_SVIDCTRL2 0x082 118 + #define INTEL_MSIC_SVIDTXLASTPKT3 0x083 /* RO */ 119 + #define INTEL_MSIC_SVIDTXLASTPKT2 0x084 /* RO */ 120 + #define INTEL_MSIC_SVIDTXLASTPKT1 0x085 /* RO */ 121 + #define INTEL_MSIC_SVIDTXLASTPKT0 0x086 /* RO */ 122 + #define INTEL_MSIC_SVIDPKTOUTBYTE3 0x087 123 + #define INTEL_MSIC_SVIDPKTOUTBYTE2 0x088 124 + #define INTEL_MSIC_SVIDPKTOUTBYTE1 0x089 125 + #define INTEL_MSIC_SVIDPKTOUTBYTE0 0x08a 126 + #define INTEL_MSIC_SVIDRXVPDEBUG1 0x08b 127 + #define INTEL_MSIC_SVIDRXVPDEBUG0 0x08c 128 + #define INTEL_MSIC_SVIDRXLASTPKT3 0x08d /* RO */ 129 + #define INTEL_MSIC_SVIDRXLASTPKT2 0x08e /* RO */ 130 + #define INTEL_MSIC_SVIDRXLASTPKT1 0x08f /* RO */ 131 + #define INTEL_MSIC_SVIDRXLASTPKT0 0x090 /* RO */ 132 + #define INTEL_MSIC_SVIDRXCHKSTATUS3 0x091 /* RO */ 133 + #define INTEL_MSIC_SVIDRXCHKSTATUS2 0x092 /* RO */ 134 + #define INTEL_MSIC_SVIDRXCHKSTATUS1 0x093 /* RO */ 135 + #define INTEL_MSIC_SVIDRXCHKSTATUS0 0x094 /* RO */ 136 + 137 + /* VREG */ 138 + #define INTEL_MSIC_VCCLATCH 0x0c0 139 + #define INTEL_MSIC_VNNLATCH 0x0c1 140 + #define INTEL_MSIC_VCCCNT 0x0c2 141 + #define INTEL_MSIC_SMPSRAMP 0x0c3 142 + #define INTEL_MSIC_VNNCNT 0x0c4 143 + #define INTEL_MSIC_VNNAONCNT 0x0c5 144 + #define INTEL_MSIC_VCC122AONCNT 0x0c6 145 + #define INTEL_MSIC_V180AONCNT 0x0c7 146 + #define INTEL_MSIC_V500CNT 0x0c8 147 + #define INTEL_MSIC_VIHFCNT 0x0c9 148 + #define INTEL_MSIC_LDORAMP1 0x0ca 149 + #define INTEL_MSIC_LDORAMP2 0x0cb 150 + #define INTEL_MSIC_VCC108AONCNT 0x0cc 151 + #define INTEL_MSIC_VCC108ASCNT 0x0cd 152 + #define INTEL_MSIC_VCC108CNT 0x0ce 153 + #define INTEL_MSIC_VCCA100ASCNT 0x0cf 154 + #define INTEL_MSIC_VCCA100CNT 0x0d0 155 + #define INTEL_MSIC_VCC180AONCNT 0x0d1 156 + #define INTEL_MSIC_VCC180CNT 0x0d2 157 + #define INTEL_MSIC_VCC330CNT 0x0d3 158 + #define INTEL_MSIC_VUSB330CNT 0x0d4 159 + #define INTEL_MSIC_VCCSDIOCNT 0x0d5 160 + #define INTEL_MSIC_VPROG1CNT 0x0d6 161 + #define INTEL_MSIC_VPROG2CNT 0x0d7 162 + #define INTEL_MSIC_VEMMCSCNT 0x0d8 163 + #define INTEL_MSIC_VEMMC1CNT 0x0d9 164 + #define INTEL_MSIC_VEMMC2CNT 0x0da 165 + #define INTEL_MSIC_VAUDACNT 0x0db 166 + #define INTEL_MSIC_VHSPCNT 0x0dc 167 + #define INTEL_MSIC_VHSNCNT 0x0dd 168 + #define INTEL_MSIC_VHDMICNT 0x0de 169 + #define INTEL_MSIC_VOTGCNT 0x0df 170 + #define INTEL_MSIC_V1P35CNT 0x0e0 171 + #define INTEL_MSIC_V330AONCNT 0x0e1 172 + 173 + /* RESET */ 174 + #define INTEL_MSIC_CHIPCNTRL 0x100 /* WO */ 175 + #define INTEL_MSIC_ERCONFIG 0x101 176 + 177 + /* BURST */ 178 + #define INTEL_MSIC_BATCURRENTLIMIT12 0x102 179 + #define INTEL_MSIC_BATTIMELIMIT12 0x103 180 + #define INTEL_MSIC_BATTIMELIMIT3 0x104 181 + #define INTEL_MSIC_BATTIMEDB 0x105 182 + #define INTEL_MSIC_BRSTCONFIGOUTPUTS 0x106 183 + #define INTEL_MSIC_BRSTCONFIGACTIONS 0x107 184 + #define INTEL_MSIC_BURSTCONTROLSTATUS 0x108 185 + 186 + /* RTC */ 187 + #define INTEL_MSIC_RTCB1 0x140 /* RO */ 188 + #define INTEL_MSIC_RTCB2 0x141 /* RO */ 189 + #define INTEL_MSIC_RTCB3 0x142 /* RO */ 190 + #define INTEL_MSIC_RTCB4 0x143 /* RO */ 191 + #define INTEL_MSIC_RTCOB1 0x144 192 + #define INTEL_MSIC_RTCOB2 0x145 193 + #define INTEL_MSIC_RTCOB3 0x146 194 + #define INTEL_MSIC_RTCOB4 0x147 195 + #define INTEL_MSIC_RTCAB1 0x148 196 + #define INTEL_MSIC_RTCAB2 0x149 197 + #define INTEL_MSIC_RTCAB3 0x14a 198 + #define INTEL_MSIC_RTCAB4 0x14b 199 + #define INTEL_MSIC_RTCWAB1 0x14c 200 + #define INTEL_MSIC_RTCWAB2 0x14d 201 + #define INTEL_MSIC_RTCWAB3 0x14e 202 + #define INTEL_MSIC_RTCWAB4 0x14f 203 + #define INTEL_MSIC_RTCSC1 0x150 204 + #define INTEL_MSIC_RTCSC2 0x151 205 + #define INTEL_MSIC_RTCSC3 0x152 206 + #define INTEL_MSIC_RTCSC4 0x153 207 + #define INTEL_MSIC_RTCSTATUS 0x154 /* RO */ 208 + #define INTEL_MSIC_RTCCONFIG1 0x155 209 + #define INTEL_MSIC_RTCCONFIG2 0x156 210 + 211 + /* CHARGER */ 212 + #define INTEL_MSIC_BDTIMER 0x180 213 + #define INTEL_MSIC_BATTRMV 0x181 214 + #define INTEL_MSIC_VBUSDET 0x182 215 + #define INTEL_MSIC_VBUSDET1 0x183 216 + #define INTEL_MSIC_ADPHVDET 0x184 217 + #define INTEL_MSIC_ADPLVDET 0x185 218 + #define INTEL_MSIC_ADPDETDBDM 0x186 219 + #define INTEL_MSIC_LOWBATTDET 0x187 220 + #define INTEL_MSIC_CHRCTRL 0x188 221 + #define INTEL_MSIC_CHRCVOLTAGE 0x189 222 + #define INTEL_MSIC_CHRCCURRENT 0x18a 223 + #define INTEL_MSIC_SPCHARGER 0x18b 224 + #define INTEL_MSIC_CHRTTIME 0x18c 225 + #define INTEL_MSIC_CHRCTRL1 0x18d 226 + #define INTEL_MSIC_PWRSRCLMT 0x18e 227 + #define INTEL_MSIC_CHRSTWDT 0x18f 228 + #define INTEL_MSIC_WDTWRITE 0x190 /* WO */ 229 + #define INTEL_MSIC_CHRSAFELMT 0x191 230 + #define INTEL_MSIC_SPWRSRCINT 0x192 /* RO */ 231 + #define INTEL_MSIC_SPWRSRCINT1 0x193 /* RO */ 232 + #define INTEL_MSIC_CHRLEDPWM 0x194 233 + #define INTEL_MSIC_CHRLEDCTRL 0x195 234 + 235 + /* ADC */ 236 + #define INTEL_MSIC_ADC1CNTL1 0x1c0 237 + #define INTEL_MSIC_ADC1CNTL2 0x1c1 238 + #define INTEL_MSIC_ADC1CNTL3 0x1c2 239 + #define INTEL_MSIC_ADC1OFFSETH 0x1c3 /* RO */ 240 + #define INTEL_MSIC_ADC1OFFSETL 0x1c4 /* RO */ 241 + #define INTEL_MSIC_ADC1ADDR0 0x1c5 242 + #define INTEL_MSIC_ADC1ADDR1 0x1c6 243 + #define INTEL_MSIC_ADC1ADDR2 0x1c7 244 + #define INTEL_MSIC_ADC1ADDR3 0x1c8 245 + #define INTEL_MSIC_ADC1ADDR4 0x1c9 246 + #define INTEL_MSIC_ADC1ADDR5 0x1ca 247 + #define INTEL_MSIC_ADC1ADDR6 0x1cb 248 + #define INTEL_MSIC_ADC1ADDR7 0x1cc 249 + #define INTEL_MSIC_ADC1ADDR8 0x1cd 250 + #define INTEL_MSIC_ADC1ADDR9 0x1ce 251 + #define INTEL_MSIC_ADC1ADDR10 0x1cf 252 + #define INTEL_MSIC_ADC1ADDR11 0x1d0 253 + #define INTEL_MSIC_ADC1ADDR12 0x1d1 254 + #define INTEL_MSIC_ADC1ADDR13 0x1d2 255 + #define INTEL_MSIC_ADC1ADDR14 0x1d3 256 + #define INTEL_MSIC_ADC1SNS0H 0x1d4 /* RO */ 257 + #define INTEL_MSIC_ADC1SNS0L 0x1d5 /* RO */ 258 + #define INTEL_MSIC_ADC1SNS1H 0x1d6 /* RO */ 259 + #define INTEL_MSIC_ADC1SNS1L 0x1d7 /* RO */ 260 + #define INTEL_MSIC_ADC1SNS2H 0x1d8 /* RO */ 261 + #define INTEL_MSIC_ADC1SNS2L 0x1d9 /* RO */ 262 + #define INTEL_MSIC_ADC1SNS3H 0x1da /* RO */ 263 + #define INTEL_MSIC_ADC1SNS3L 0x1db /* RO */ 264 + #define INTEL_MSIC_ADC1SNS4H 0x1dc /* RO */ 265 + #define INTEL_MSIC_ADC1SNS4L 0x1dd /* RO */ 266 + #define INTEL_MSIC_ADC1SNS5H 0x1de /* RO */ 267 + #define INTEL_MSIC_ADC1SNS5L 0x1df /* RO */ 268 + #define INTEL_MSIC_ADC1SNS6H 0x1e0 /* RO */ 269 + #define INTEL_MSIC_ADC1SNS6L 0x1e1 /* RO */ 270 + #define INTEL_MSIC_ADC1SNS7H 0x1e2 /* RO */ 271 + #define INTEL_MSIC_ADC1SNS7L 0x1e3 /* RO */ 272 + #define INTEL_MSIC_ADC1SNS8H 0x1e4 /* RO */ 273 + #define INTEL_MSIC_ADC1SNS8L 0x1e5 /* RO */ 274 + #define INTEL_MSIC_ADC1SNS9H 0x1e6 /* RO */ 275 + #define INTEL_MSIC_ADC1SNS9L 0x1e7 /* RO */ 276 + #define INTEL_MSIC_ADC1SNS10H 0x1e8 /* RO */ 277 + #define INTEL_MSIC_ADC1SNS10L 0x1e9 /* RO */ 278 + #define INTEL_MSIC_ADC1SNS11H 0x1ea /* RO */ 279 + #define INTEL_MSIC_ADC1SNS11L 0x1eb /* RO */ 280 + #define INTEL_MSIC_ADC1SNS12H 0x1ec /* RO */ 281 + #define INTEL_MSIC_ADC1SNS12L 0x1ed /* RO */ 282 + #define INTEL_MSIC_ADC1SNS13H 0x1ee /* RO */ 283 + #define INTEL_MSIC_ADC1SNS13L 0x1ef /* RO */ 284 + #define INTEL_MSIC_ADC1SNS14H 0x1f0 /* RO */ 285 + #define INTEL_MSIC_ADC1SNS14L 0x1f1 /* RO */ 286 + #define INTEL_MSIC_ADC1BV0H 0x1f2 /* RO */ 287 + #define INTEL_MSIC_ADC1BV0L 0x1f3 /* RO */ 288 + #define INTEL_MSIC_ADC1BV1H 0x1f4 /* RO */ 289 + #define INTEL_MSIC_ADC1BV1L 0x1f5 /* RO */ 290 + #define INTEL_MSIC_ADC1BV2H 0x1f6 /* RO */ 291 + #define INTEL_MSIC_ADC1BV2L 0x1f7 /* RO */ 292 + #define INTEL_MSIC_ADC1BV3H 0x1f8 /* RO */ 293 + #define INTEL_MSIC_ADC1BV3L 0x1f9 /* RO */ 294 + #define INTEL_MSIC_ADC1BI0H 0x1fa /* RO */ 295 + #define INTEL_MSIC_ADC1BI0L 0x1fb /* RO */ 296 + #define INTEL_MSIC_ADC1BI1H 0x1fc /* RO */ 297 + #define INTEL_MSIC_ADC1BI1L 0x1fd /* RO */ 298 + #define INTEL_MSIC_ADC1BI2H 0x1fe /* RO */ 299 + #define INTEL_MSIC_ADC1BI2L 0x1ff /* RO */ 300 + #define INTEL_MSIC_ADC1BI3H 0x200 /* RO */ 301 + #define INTEL_MSIC_ADC1BI3L 0x201 /* RO */ 302 + #define INTEL_MSIC_CCCNTL 0x202 303 + #define INTEL_MSIC_CCOFFSETH 0x203 /* RO */ 304 + #define INTEL_MSIC_CCOFFSETL 0x204 /* RO */ 305 + #define INTEL_MSIC_CCADCHA 0x205 /* RO */ 306 + #define INTEL_MSIC_CCADCLA 0x206 /* RO */ 307 + 308 + /* AUDIO */ 309 + #define INTEL_MSIC_AUDPLLCTRL 0x240 310 + #define INTEL_MSIC_DMICBUF0123 0x241 311 + #define INTEL_MSIC_DMICBUF45 0x242 312 + #define INTEL_MSIC_DMICGPO 0x244 313 + #define INTEL_MSIC_DMICMUX 0x245 314 + #define INTEL_MSIC_DMICCLK 0x246 315 + #define INTEL_MSIC_MICBIAS 0x247 316 + #define INTEL_MSIC_ADCCONFIG 0x248 317 + #define INTEL_MSIC_MICAMP1 0x249 318 + #define INTEL_MSIC_MICAMP2 0x24a 319 + #define INTEL_MSIC_NOISEMUX 0x24b 320 + #define INTEL_MSIC_AUDIOMUX12 0x24c 321 + #define INTEL_MSIC_AUDIOMUX34 0x24d 322 + #define INTEL_MSIC_AUDIOSINC 0x24e 323 + #define INTEL_MSIC_AUDIOTXEN 0x24f 324 + #define INTEL_MSIC_HSEPRXCTRL 0x250 325 + #define INTEL_MSIC_IHFRXCTRL 0x251 326 + #define INTEL_MSIC_VOICETXVOL 0x252 327 + #define INTEL_MSIC_SIDETONEVOL 0x253 328 + #define INTEL_MSIC_MUSICSHARVOL 0x254 329 + #define INTEL_MSIC_VOICETXCTRL 0x255 330 + #define INTEL_MSIC_HSMIXER 0x256 331 + #define INTEL_MSIC_DACCONFIG 0x257 332 + #define INTEL_MSIC_SOFTMUTE 0x258 333 + #define INTEL_MSIC_HSLVOLCTRL 0x259 334 + #define INTEL_MSIC_HSRVOLCTRL 0x25a 335 + #define INTEL_MSIC_IHFLVOLCTRL 0x25b 336 + #define INTEL_MSIC_IHFRVOLCTRL 0x25c 337 + #define INTEL_MSIC_DRIVEREN 0x25d 338 + #define INTEL_MSIC_LINEOUTCTRL 0x25e 339 + #define INTEL_MSIC_VIB1CTRL1 0x25f 340 + #define INTEL_MSIC_VIB1CTRL2 0x260 341 + #define INTEL_MSIC_VIB1CTRL3 0x261 342 + #define INTEL_MSIC_VIB1SPIPCM_1 0x262 343 + #define INTEL_MSIC_VIB1SPIPCM_2 0x263 344 + #define INTEL_MSIC_VIB1CTRL5 0x264 345 + #define INTEL_MSIC_VIB2CTRL1 0x265 346 + #define INTEL_MSIC_VIB2CTRL2 0x266 347 + #define INTEL_MSIC_VIB2CTRL3 0x267 348 + #define INTEL_MSIC_VIB2SPIPCM_1 0x268 349 + #define INTEL_MSIC_VIB2SPIPCM_2 0x269 350 + #define INTEL_MSIC_VIB2CTRL5 0x26a 351 + #define INTEL_MSIC_BTNCTRL1 0x26b 352 + #define INTEL_MSIC_BTNCTRL2 0x26c 353 + #define INTEL_MSIC_PCM1TXSLOT01 0x26d 354 + #define INTEL_MSIC_PCM1TXSLOT23 0x26e 355 + #define INTEL_MSIC_PCM1TXSLOT45 0x26f 356 + #define INTEL_MSIC_PCM1RXSLOT0123 0x270 357 + #define INTEL_MSIC_PCM1RXSLOT045 0x271 358 + #define INTEL_MSIC_PCM2TXSLOT01 0x272 359 + #define INTEL_MSIC_PCM2TXSLOT23 0x273 360 + #define INTEL_MSIC_PCM2TXSLOT45 0x274 361 + #define INTEL_MSIC_PCM2RXSLOT01 0x275 362 + #define INTEL_MSIC_PCM2RXSLOT23 0x276 363 + #define INTEL_MSIC_PCM2RXSLOT45 0x277 364 + #define INTEL_MSIC_PCM1CTRL1 0x278 365 + #define INTEL_MSIC_PCM1CTRL2 0x279 366 + #define INTEL_MSIC_PCM1CTRL3 0x27a 367 + #define INTEL_MSIC_PCM2CTRL1 0x27b 368 + #define INTEL_MSIC_PCM2CTRL2 0x27c 369 + 370 + /* HDMI */ 371 + #define INTEL_MSIC_HDMIPUEN 0x280 372 + #define INTEL_MSIC_HDMISTATUS 0x281 /* RO */ 373 + 374 + /* Physical address of the start of the MSIC interrupt tree in SRAM */ 375 + #define INTEL_MSIC_IRQ_PHYS_BASE 0xffff7fc0 376 + 377 + /** 378 + * struct intel_msic_gpio_pdata - platform data for the MSIC GPIO driver 379 + * @gpio_base: base number for the GPIOs 380 + */ 381 + struct intel_msic_gpio_pdata { 382 + unsigned gpio_base; 383 + }; 384 + 385 + /** 386 + * struct intel_msic_ocd_pdata - platform data for the MSIC OCD driver 387 + * @gpio: GPIO number used for OCD interrupts 388 + * 389 + * The MSIC MFD driver converts @gpio into an IRQ number and passes it to 390 + * the OCD driver as %IORESOURCE_IRQ. 391 + */ 392 + struct intel_msic_ocd_pdata { 393 + unsigned gpio; 394 + }; 395 + 396 + /* MSIC embedded blocks (subdevices) */ 397 + enum intel_msic_block { 398 + INTEL_MSIC_BLOCK_TOUCH, 399 + INTEL_MSIC_BLOCK_ADC, 400 + INTEL_MSIC_BLOCK_BATTERY, 401 + INTEL_MSIC_BLOCK_GPIO, 402 + INTEL_MSIC_BLOCK_AUDIO, 403 + INTEL_MSIC_BLOCK_HDMI, 404 + INTEL_MSIC_BLOCK_THERMAL, 405 + INTEL_MSIC_BLOCK_POWER_BTN, 406 + INTEL_MSIC_BLOCK_OCD, 407 + 408 + INTEL_MSIC_BLOCK_LAST, 409 + }; 410 + 411 + /** 412 + * struct intel_msic_platform_data - platform data for the MSIC driver 413 + * @irq: array of interrupt numbers, one per device. If @irq is set to %0 414 + * for a given block, the corresponding platform device is not 415 + * created. For devices which don't have an interrupt, use %0xff 416 + * (this is same as in SFI spec). 417 + * @gpio: platform data for the MSIC GPIO driver 418 + * @ocd: platform data for the MSIC OCD driver 419 + * 420 + * Once the MSIC driver is initialized, the register interface is ready to 421 + * use. All the platform devices for subdevices are created after the 422 + * register interface is ready so that we can guarantee its availability to 423 + * the subdevice drivers. 424 + * 425 + * Interrupt numbers are passed to the subdevices via %IORESOURCE_IRQ 426 + * resources of the created platform device. 427 + */ 428 + struct intel_msic_platform_data { 429 + int irq[INTEL_MSIC_BLOCK_LAST]; 430 + struct intel_msic_gpio_pdata *gpio; 431 + struct intel_msic_ocd_pdata *ocd; 432 + }; 433 + 434 + struct intel_msic; 435 + 436 + extern int intel_msic_reg_read(unsigned short reg, u8 *val); 437 + extern int intel_msic_reg_write(unsigned short reg, u8 val); 438 + extern int intel_msic_reg_update(unsigned short reg, u8 val, u8 mask); 439 + extern int intel_msic_bulk_read(unsigned short *reg, u8 *buf, size_t count); 440 + extern int intel_msic_bulk_write(unsigned short *reg, u8 *buf, size_t count); 441 + 442 + /* 443 + * pdev_to_intel_msic - gets an MSIC instance from the platform device 444 + * @pdev: platform device pointer 445 + * 446 + * The client drivers need to have pointer to the MSIC instance if they 447 + * want to call intel_msic_irq_read(). This macro can be used for 448 + * convenience to get the MSIC pointer from @pdev where needed. This is 449 + * _only_ valid for devices which are managed by the MSIC. 450 + */ 451 + #define pdev_to_intel_msic(pdev) (dev_get_drvdata(pdev->dev.parent)) 452 + 453 + extern int intel_msic_irq_read(struct intel_msic *msic, unsigned short reg, 454 + u8 *val); 455 + 456 + #endif /* __LINUX_MFD_INTEL_MSIC_H__ */