root/sound/aoa/soundbus/i2sbus/control.c

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

DEFINITIONS

This source file includes following definitions.
  1. i2sbus_control_init
  2. i2sbus_control_destroy
  3. i2sbus_control_add_dev
  4. i2sbus_control_remove_dev
  5. i2sbus_control_enable
  6. i2sbus_control_cell
  7. i2sbus_control_clock

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * i2sbus driver -- bus control routines
   4  *
   5  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/delay.h>
  10 #include <linux/slab.h>
  11 #include <linux/io.h>
  12 
  13 #include <asm/prom.h>
  14 #include <asm/macio.h>
  15 #include <asm/pmac_feature.h>
  16 #include <asm/pmac_pfunc.h>
  17 #include <asm/keylargo.h>
  18 
  19 #include "i2sbus.h"
  20 
  21 int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c)
  22 {
  23         *c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL);
  24         if (!*c)
  25                 return -ENOMEM;
  26 
  27         INIT_LIST_HEAD(&(*c)->list);
  28 
  29         (*c)->macio = dev->bus->chip;
  30         return 0;
  31 }
  32 
  33 void i2sbus_control_destroy(struct i2sbus_control *c)
  34 {
  35         kfree(c);
  36 }
  37 
  38 /* this is serialised externally */
  39 int i2sbus_control_add_dev(struct i2sbus_control *c,
  40                            struct i2sbus_dev *i2sdev)
  41 {
  42         struct device_node *np;
  43 
  44         np = i2sdev->sound.ofdev.dev.of_node;
  45         i2sdev->enable = pmf_find_function(np, "enable");
  46         i2sdev->cell_enable = pmf_find_function(np, "cell-enable");
  47         i2sdev->clock_enable = pmf_find_function(np, "clock-enable");
  48         i2sdev->cell_disable = pmf_find_function(np, "cell-disable");
  49         i2sdev->clock_disable = pmf_find_function(np, "clock-disable");
  50 
  51         /* if the bus number is not 0 or 1 we absolutely need to use
  52          * the platform functions -- there's nothing in Darwin that
  53          * would allow seeing a system behind what the FCRs are then,
  54          * and I don't want to go parsing a bunch of platform functions
  55          * by hand to try finding a system... */
  56         if (i2sdev->bus_number != 0 && i2sdev->bus_number != 1 &&
  57             (!i2sdev->enable ||
  58              !i2sdev->cell_enable || !i2sdev->clock_enable ||
  59              !i2sdev->cell_disable || !i2sdev->clock_disable)) {
  60                 pmf_put_function(i2sdev->enable);
  61                 pmf_put_function(i2sdev->cell_enable);
  62                 pmf_put_function(i2sdev->clock_enable);
  63                 pmf_put_function(i2sdev->cell_disable);
  64                 pmf_put_function(i2sdev->clock_disable);
  65                 return -ENODEV;
  66         }
  67 
  68         list_add(&i2sdev->item, &c->list);
  69 
  70         return 0;
  71 }
  72 
  73 void i2sbus_control_remove_dev(struct i2sbus_control *c,
  74                                struct i2sbus_dev *i2sdev)
  75 {
  76         /* this is serialised externally */
  77         list_del(&i2sdev->item);
  78         if (list_empty(&c->list))
  79                 i2sbus_control_destroy(c);
  80 }
  81 
  82 int i2sbus_control_enable(struct i2sbus_control *c,
  83                           struct i2sbus_dev *i2sdev)
  84 {
  85         struct pmf_args args = { .count = 0 };
  86         struct macio_chip *macio = c->macio;
  87 
  88         if (i2sdev->enable)
  89                 return pmf_call_one(i2sdev->enable, &args);
  90 
  91         if (macio == NULL || macio->base == NULL)
  92                 return -ENODEV;
  93 
  94         switch (i2sdev->bus_number) {
  95         case 0:
  96                 /* these need to be locked or done through
  97                  * newly created feature calls! */
  98                 MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
  99                 break;
 100         case 1:
 101                 MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE);
 102                 break;
 103         default:
 104                 return -ENODEV;
 105         }
 106         return 0;
 107 }
 108 
 109 int i2sbus_control_cell(struct i2sbus_control *c,
 110                         struct i2sbus_dev *i2sdev,
 111                         int enable)
 112 {
 113         struct pmf_args args = { .count = 0 };
 114         struct macio_chip *macio = c->macio;
 115 
 116         switch (enable) {
 117         case 0:
 118                 if (i2sdev->cell_disable)
 119                         return pmf_call_one(i2sdev->cell_disable, &args);
 120                 break;
 121         case 1:
 122                 if (i2sdev->cell_enable)
 123                         return pmf_call_one(i2sdev->cell_enable, &args);
 124                 break;
 125         default:
 126                 printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n");
 127                 return -ENODEV;
 128         }
 129 
 130         if (macio == NULL || macio->base == NULL)
 131                 return -ENODEV;
 132 
 133         switch (i2sdev->bus_number) {
 134         case 0:
 135                 if (enable)
 136                         MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
 137                 else
 138                         MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE);
 139                 break;
 140         case 1:
 141                 if (enable)
 142                         MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
 143                 else
 144                         MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE);
 145                 break;
 146         default:
 147                 return -ENODEV;
 148         }
 149         return 0;
 150 }
 151 
 152 int i2sbus_control_clock(struct i2sbus_control *c,
 153                          struct i2sbus_dev *i2sdev,
 154                          int enable)
 155 {
 156         struct pmf_args args = { .count = 0 };
 157         struct macio_chip *macio = c->macio;
 158 
 159         switch (enable) {
 160         case 0:
 161                 if (i2sdev->clock_disable)
 162                         return pmf_call_one(i2sdev->clock_disable, &args);
 163                 break;
 164         case 1:
 165                 if (i2sdev->clock_enable)
 166                         return pmf_call_one(i2sdev->clock_enable, &args);
 167                 break;
 168         default:
 169                 printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n");
 170                 return -ENODEV;
 171         }
 172 
 173         if (macio == NULL || macio->base == NULL)
 174                 return -ENODEV;
 175 
 176         switch (i2sdev->bus_number) {
 177         case 0:
 178                 if (enable)
 179                         MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
 180                 else
 181                         MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
 182                 break;
 183         case 1:
 184                 if (enable)
 185                         MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
 186                 else
 187                         MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT);
 188                 break;
 189         default:
 190                 return -ENODEV;
 191         }
 192         return 0;
 193 }

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