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 MFD_CELL_NAME("at91_usart_spi"); 20 21 static const struct mfd_cell at91_usart_serial_subdev = 22 MFD_CELL_NAME("atmel_usart_serial"); 23 24 static int at91_usart_mode_probe(struct platform_device *pdev) 25 { 26 const struct mfd_cell *cell; 27 u32 opmode = AT91_USART_MODE_SERIAL; 28 29 device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode); 30 31 switch (opmode) { 32 case AT91_USART_MODE_SPI: 33 cell = &at91_usart_spi_subdev; 34 break; 35 case AT91_USART_MODE_SERIAL: 36 cell = &at91_usart_serial_subdev; 37 break; 38 default: 39 dev_err(&pdev->dev, "atmel,usart-mode has an invalid value %u\n", 40 opmode); 41 return -EINVAL; 42 } 43 44 return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, cell, 1, 45 NULL, 0, NULL); 46 } 47 48 static const struct of_device_id at91_usart_mode_of_match[] = { 49 { .compatible = "atmel,at91rm9200-usart" }, 50 { .compatible = "atmel,at91sam9260-usart" }, 51 { /* sentinel */ } 52 }; 53 54 MODULE_DEVICE_TABLE(of, at91_usart_mode_of_match); 55 56 static struct platform_driver at91_usart_mfd = { 57 .probe = at91_usart_mode_probe, 58 .driver = { 59 .name = "at91_usart_mode", 60 .of_match_table = at91_usart_mode_of_match, 61 }, 62 }; 63 64 module_platform_driver(at91_usart_mfd); 65 66 MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>"); 67 MODULE_DESCRIPTION("AT91 USART MFD driver"); 68 MODULE_LICENSE("GPL v2"); 69