1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for AT91 USART 4 * 5 * Copyright (C) 2018 Microchip Technology 6 * 7 * Author: Radu Pirea <radu.pirea@microchip.com> 8 * 9 */ 10 11 #include <dt-bindings/mfd/at91-usart.h> 12 13 #include <linux/module.h> 14 #include <linux/mfd/core.h> 15 #include <linux/of.h> 16 #include <linux/property.h> 17 18 static const struct mfd_cell at91_usart_spi_subdev = { 19 .name = "at91_usart_spi", 20 .of_compatible = "microchip,at91sam9g45-usart-spi", 21 }; 22 23 static const struct mfd_cell at91_usart_serial_subdev = { 24 .name = "atmel_usart_serial", 25 .of_compatible = "atmel,at91rm9200-usart-serial", 26 }; 27 28 static int at91_usart_mode_probe(struct platform_device *pdev) 29 { 30 const struct mfd_cell *cell; 31 u32 opmode = AT91_USART_MODE_SERIAL; 32 33 device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode); 34 35 switch (opmode) { 36 case AT91_USART_MODE_SPI: 37 cell = &at91_usart_spi_subdev; 38 break; 39 case AT91_USART_MODE_SERIAL: 40 cell = &at91_usart_serial_subdev; 41 break; 42 default: 43 dev_err(&pdev->dev, "atmel,usart-mode has an invalid value %u\n", 44 opmode); 45 return -EINVAL; 46 } 47 48 return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, cell, 1, 49 NULL, 0, NULL); 50 } 51 52 static const struct of_device_id at91_usart_mode_of_match[] = { 53 { .compatible = "atmel,at91rm9200-usart" }, 54 { .compatible = "atmel,at91sam9260-usart" }, 55 { /* sentinel */ } 56 }; 57 58 MODULE_DEVICE_TABLE(of, at91_usart_mode_of_match); 59 60 static struct platform_driver at91_usart_mfd = { 61 .probe = at91_usart_mode_probe, 62 .driver = { 63 .name = "at91_usart_mode", 64 .of_match_table = at91_usart_mode_of_match, 65 }, 66 }; 67 68 module_platform_driver(at91_usart_mfd); 69 70 MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>"); 71 MODULE_DESCRIPTION("AT91 USART MFD driver"); 72 MODULE_LICENSE("GPL v2"); 73