14ab11996SSrinivas Kandagatla /* 24ab11996SSrinivas Kandagatla * Copyright (C) 2015 Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 34ab11996SSrinivas Kandagatla * 44ab11996SSrinivas Kandagatla * This program is free software; you can redistribute it and/or modify 54ab11996SSrinivas Kandagatla * it under the terms of the GNU General Public License version 2 and 64ab11996SSrinivas Kandagatla * only version 2 as published by the Free Software Foundation. 74ab11996SSrinivas Kandagatla * 84ab11996SSrinivas Kandagatla * This program is distributed in the hope that it will be useful, 94ab11996SSrinivas Kandagatla * but WITHOUT ANY WARRANTY; without even the implied warranty of 104ab11996SSrinivas Kandagatla * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 114ab11996SSrinivas Kandagatla * GNU General Public License for more details. 124ab11996SSrinivas Kandagatla */ 134ab11996SSrinivas Kandagatla 144ab11996SSrinivas Kandagatla #include <linux/device.h> 154ab11996SSrinivas Kandagatla #include <linux/module.h> 16382c62f7SSrinivas Kandagatla #include <linux/io.h> 174ab11996SSrinivas Kandagatla #include <linux/nvmem-provider.h> 184ab11996SSrinivas Kandagatla #include <linux/platform_device.h> 194ab11996SSrinivas Kandagatla 20382c62f7SSrinivas Kandagatla static int qfprom_reg_read(void *context, 21382c62f7SSrinivas Kandagatla unsigned int reg, void *_val, size_t bytes) 22382c62f7SSrinivas Kandagatla { 23382c62f7SSrinivas Kandagatla void __iomem *base = context; 24*01d0d2c4SVivek Gautam u8 *val = _val; 25*01d0d2c4SVivek Gautam int i = 0, words = bytes; 264ab11996SSrinivas Kandagatla 27382c62f7SSrinivas Kandagatla while (words--) 28*01d0d2c4SVivek Gautam *val++ = readb(base + reg + i++); 29382c62f7SSrinivas Kandagatla 30382c62f7SSrinivas Kandagatla return 0; 31382c62f7SSrinivas Kandagatla } 32382c62f7SSrinivas Kandagatla 33382c62f7SSrinivas Kandagatla static int qfprom_reg_write(void *context, 34382c62f7SSrinivas Kandagatla unsigned int reg, void *_val, size_t bytes) 35382c62f7SSrinivas Kandagatla { 36382c62f7SSrinivas Kandagatla void __iomem *base = context; 37*01d0d2c4SVivek Gautam u8 *val = _val; 38*01d0d2c4SVivek Gautam int i = 0, words = bytes; 39382c62f7SSrinivas Kandagatla 40382c62f7SSrinivas Kandagatla while (words--) 41*01d0d2c4SVivek Gautam writeb(*val++, base + reg + i++); 42382c62f7SSrinivas Kandagatla 43382c62f7SSrinivas Kandagatla return 0; 44382c62f7SSrinivas Kandagatla } 454ab11996SSrinivas Kandagatla 464ab11996SSrinivas Kandagatla static int qfprom_remove(struct platform_device *pdev) 474ab11996SSrinivas Kandagatla { 484ab11996SSrinivas Kandagatla struct nvmem_device *nvmem = platform_get_drvdata(pdev); 494ab11996SSrinivas Kandagatla 504ab11996SSrinivas Kandagatla return nvmem_unregister(nvmem); 514ab11996SSrinivas Kandagatla } 524ab11996SSrinivas Kandagatla 53382c62f7SSrinivas Kandagatla static struct nvmem_config econfig = { 54382c62f7SSrinivas Kandagatla .name = "qfprom", 55382c62f7SSrinivas Kandagatla .owner = THIS_MODULE, 56*01d0d2c4SVivek Gautam .stride = 1, 57382c62f7SSrinivas Kandagatla .word_size = 1, 58382c62f7SSrinivas Kandagatla .reg_read = qfprom_reg_read, 59382c62f7SSrinivas Kandagatla .reg_write = qfprom_reg_write, 60382c62f7SSrinivas Kandagatla }; 61382c62f7SSrinivas Kandagatla 624ab11996SSrinivas Kandagatla static int qfprom_probe(struct platform_device *pdev) 634ab11996SSrinivas Kandagatla { 644ab11996SSrinivas Kandagatla struct device *dev = &pdev->dev; 654ab11996SSrinivas Kandagatla struct resource *res; 664ab11996SSrinivas Kandagatla struct nvmem_device *nvmem; 674ab11996SSrinivas Kandagatla void __iomem *base; 684ab11996SSrinivas Kandagatla 694ab11996SSrinivas Kandagatla res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 704ab11996SSrinivas Kandagatla base = devm_ioremap_resource(dev, res); 714ab11996SSrinivas Kandagatla if (IS_ERR(base)) 724ab11996SSrinivas Kandagatla return PTR_ERR(base); 734ab11996SSrinivas Kandagatla 74382c62f7SSrinivas Kandagatla econfig.size = resource_size(res); 754ab11996SSrinivas Kandagatla econfig.dev = dev; 76382c62f7SSrinivas Kandagatla econfig.priv = base; 77382c62f7SSrinivas Kandagatla 784ab11996SSrinivas Kandagatla nvmem = nvmem_register(&econfig); 794ab11996SSrinivas Kandagatla if (IS_ERR(nvmem)) 804ab11996SSrinivas Kandagatla return PTR_ERR(nvmem); 814ab11996SSrinivas Kandagatla 824ab11996SSrinivas Kandagatla platform_set_drvdata(pdev, nvmem); 834ab11996SSrinivas Kandagatla 844ab11996SSrinivas Kandagatla return 0; 854ab11996SSrinivas Kandagatla } 864ab11996SSrinivas Kandagatla 874ab11996SSrinivas Kandagatla static const struct of_device_id qfprom_of_match[] = { 884ab11996SSrinivas Kandagatla { .compatible = "qcom,qfprom",}, 894ab11996SSrinivas Kandagatla {/* sentinel */}, 904ab11996SSrinivas Kandagatla }; 914ab11996SSrinivas Kandagatla MODULE_DEVICE_TABLE(of, qfprom_of_match); 924ab11996SSrinivas Kandagatla 934ab11996SSrinivas Kandagatla static struct platform_driver qfprom_driver = { 944ab11996SSrinivas Kandagatla .probe = qfprom_probe, 954ab11996SSrinivas Kandagatla .remove = qfprom_remove, 964ab11996SSrinivas Kandagatla .driver = { 974ab11996SSrinivas Kandagatla .name = "qcom,qfprom", 984ab11996SSrinivas Kandagatla .of_match_table = qfprom_of_match, 994ab11996SSrinivas Kandagatla }, 1004ab11996SSrinivas Kandagatla }; 1014ab11996SSrinivas Kandagatla module_platform_driver(qfprom_driver); 1024ab11996SSrinivas Kandagatla MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>"); 1034ab11996SSrinivas Kandagatla MODULE_DESCRIPTION("Qualcomm QFPROM driver"); 1044ab11996SSrinivas Kandagatla MODULE_LICENSE("GPL v2"); 105