root/drivers/mfd/menf21bmc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. menf21bmc_wdt_exit_prod_mode
  2. menf21bmc_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  MEN 14F021P00 Board Management Controller (BMC) MFD Core Driver.
   4  *
   5  *  Copyright (C) 2014 MEN Mikro Elektronik Nuernberg GmbH
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/device.h>
  10 #include <linux/module.h>
  11 #include <linux/i2c.h>
  12 #include <linux/mfd/core.h>
  13 
  14 #define BMC_CMD_WDT_EXIT_PROD   0x18
  15 #define BMC_CMD_WDT_PROD_STAT   0x19
  16 #define BMC_CMD_REV_MAJOR       0x80
  17 #define BMC_CMD_REV_MINOR       0x81
  18 #define BMC_CMD_REV_MAIN        0x82
  19 
  20 static struct mfd_cell menf21bmc_cell[] = {
  21         { .name = "menf21bmc_wdt", },
  22         { .name = "menf21bmc_led", },
  23         { .name = "menf21bmc_hwmon", }
  24 };
  25 
  26 static int menf21bmc_wdt_exit_prod_mode(struct i2c_client *client)
  27 {
  28         int val, ret;
  29 
  30         val = i2c_smbus_read_byte_data(client, BMC_CMD_WDT_PROD_STAT);
  31         if (val < 0)
  32                 return val;
  33 
  34         /*
  35          * Production mode should be not active after delivery of the Board.
  36          * To be sure we check it, inform the user and exit the mode
  37          * if active.
  38          */
  39         if (val == 0x00) {
  40                 dev_info(&client->dev,
  41                         "BMC in production mode. Exit production mode\n");
  42 
  43                 ret = i2c_smbus_write_byte(client, BMC_CMD_WDT_EXIT_PROD);
  44                 if (ret < 0)
  45                         return ret;
  46         }
  47 
  48         return 0;
  49 }
  50 
  51 static int
  52 menf21bmc_probe(struct i2c_client *client, const struct i2c_device_id *ids)
  53 {
  54         int rev_major, rev_minor, rev_main;
  55         int ret;
  56 
  57         ret = i2c_check_functionality(client->adapter,
  58                                       I2C_FUNC_SMBUS_BYTE_DATA |
  59                                       I2C_FUNC_SMBUS_WORD_DATA |
  60                                       I2C_FUNC_SMBUS_BYTE);
  61         if (!ret)
  62                 return -ENODEV;
  63 
  64         rev_major = i2c_smbus_read_word_data(client, BMC_CMD_REV_MAJOR);
  65         if (rev_major < 0) {
  66                 dev_err(&client->dev, "failed to get BMC major revision\n");
  67                 return rev_major;
  68         }
  69 
  70         rev_minor = i2c_smbus_read_word_data(client, BMC_CMD_REV_MINOR);
  71         if (rev_minor < 0) {
  72                 dev_err(&client->dev, "failed to get BMC minor revision\n");
  73                 return rev_minor;
  74         }
  75 
  76         rev_main = i2c_smbus_read_word_data(client, BMC_CMD_REV_MAIN);
  77         if (rev_main < 0) {
  78                 dev_err(&client->dev, "failed to get BMC main revision\n");
  79                 return rev_main;
  80         }
  81 
  82         dev_info(&client->dev, "FW Revision: %02d.%02d.%02d\n",
  83                  rev_major, rev_minor, rev_main);
  84 
  85         /*
  86          * We have to exit the Production Mode of the BMC to activate the
  87          * Watchdog functionality and the BIOS life sign monitoring.
  88          */
  89         ret = menf21bmc_wdt_exit_prod_mode(client);
  90         if (ret < 0) {
  91                 dev_err(&client->dev, "failed to leave production mode\n");
  92                 return ret;
  93         }
  94 
  95         ret = devm_mfd_add_devices(&client->dev, 0, menf21bmc_cell,
  96                                    ARRAY_SIZE(menf21bmc_cell), NULL, 0, NULL);
  97         if (ret < 0) {
  98                 dev_err(&client->dev, "failed to add BMC sub-devices\n");
  99                 return ret;
 100         }
 101 
 102         return 0;
 103 }
 104 
 105 static const struct i2c_device_id menf21bmc_id_table[] = {
 106         { "menf21bmc" },
 107         { }
 108 };
 109 MODULE_DEVICE_TABLE(i2c, menf21bmc_id_table);
 110 
 111 static struct i2c_driver menf21bmc_driver = {
 112         .driver.name    = "menf21bmc",
 113         .id_table       = menf21bmc_id_table,
 114         .probe          = menf21bmc_probe,
 115 };
 116 
 117 module_i2c_driver(menf21bmc_driver);
 118 
 119 MODULE_DESCRIPTION("MEN 14F021P00 BMC mfd core driver");
 120 MODULE_AUTHOR("Andreas Werner <andreas.werner@men.de>");
 121 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */